#include <cstdio> #include <vector> #include <set> #include <algorithm> using namespace std; int parent[ 100005 ], n; pair < pair <int,int> , pair <int,int> > plemiona[ 100005 ]; set < pair < pair <int,int>, int > > drzewo[ 8000005 ], drzewo2[ 8000005 ]; vector < pair < pair <int,int> , pair <int,int> > > result; void erase_tree(int pos, int s, int e, int cs, int ce, pair < pair <int,int>, int > v); bool add_tree(int pos, int s, int e, int cs, int ce, pair < pair <int,int>, int > v ); int find( int a ); void _union(int a, int b); void erase_tree(int pos, int s, int e, int cs, int ce, pair < pair <int,int>, int > v){ if (drzewo2[ pos ].find( v ) != drzewo2[ pos ].end()){ drzewo2[ pos ].erase( v ); } if ((s == cs) && (e == ce)){ if (drzewo[ pos ].find( v ) != drzewo[ pos ].end()){ drzewo[ pos ].erase( v ); } } else if ((s <= (cs+ce)/2) && (e <= (cs+ce)/2)){ erase_tree( pos*2, s, e, cs, (cs+ce)/2, v); } else if ((s > (cs+ce)/2) && (e > (cs+ce)/2)){ erase_tree( pos*2+1, s, e, (cs+ce)/2+1, ce, v); } else { erase_tree( pos*2, s, (cs+ce)/2, cs, (cs+ce)/2, v); erase_tree( pos*2+1, (cs+ce)/2+1, e, (cs+ce)/2+1, ce, v); } } bool add_tree(int pos, int s, int e, int cs, int ce, pair < pair <int,int>, int > v ){ set < pair < pair <int,int>, int > >::iterator it = drzewo[ pos ].upper_bound( make_pair( make_pair( v.first.first, -1), -1 )); if ((it != drzewo[pos].end()) && ((*it).first.first <= v.first.second)){ _union( v.second, (*it).second ); return true; } else { if (it != drzewo[pos].begin()){ it--; if ((it != drzewo[pos].end()) && (v.first.first <= (*it).first.second)){ _union( v.second, (*it).second ); return true; } } } if ((s == cs) && (e == ce)){ drzewo[ pos ].insert( v ); set < pair < pair <int,int>, int > >::iterator it = drzewo2[ pos ].upper_bound( make_pair( make_pair( v.first.first, -1), -1 )); if ((it != drzewo2[pos].end()) && ((*it).first.first <= v.first.second)){ _union( v.second, (*it).second ); return true; } else { if (it != drzewo2[pos].begin()){ it--; if ((it != drzewo2[pos].end()) && (v.first.first <= (*it).first.second)){ _union( v.second, (*it).second ); return true; } } } } else if ((s <= (cs+ce)/2) && (e <= (cs+ce)/2)){ drzewo2[ pos ].insert( v ); add_tree(pos*2, s, e, cs, (cs+ce)/2, v); } else if ((s > (cs+ce)/2) && (e > (cs+ce)/2)){ drzewo2[ pos ].insert( v ); add_tree(pos*2+1, s, e, (cs+ce)/2+1, ce, v); } else { drzewo2[ pos ].insert( v ); bool t = add_tree(pos*2, s, (cs+ce)/2, cs, (cs+ce)/2, v); if (t) return true; add_tree(pos*2+1, (cs+ce)/2+1, e, (cs+ce)/2+1, ce, v); } return false; } int find( int a ){ if (parent[a] == a){ return a; } else { parent[a] = find( parent[a] ); return parent[a]; } } void _union(int a, int b){ //printf("%d %d %d %d %d %d %d %d\n", plemiona[3].first.first, plemiona[3].first.second, plemiona[3].second.first, plemiona[3].second.second, plemiona[5].first.first, plemiona[5].first.second, plemiona[5].second.first, plemiona[5].second.second); erase_tree( 1, plemiona[a].first.first * 2 + 1, plemiona[ a ].first.second * 2 , 1, 2000000, make_pair( make_pair( plemiona[a].second.first * 2 + 1, plemiona[a].second.second * 2 ), a )); erase_tree( 1, plemiona[b].first.first * 2 + 1, plemiona[ b ].first.second * 2 , 1, 2000000, make_pair( make_pair( plemiona[b].second.first * 2 + 1, plemiona[b].second.second * 2 ), b )); pair < pair <int,int> , pair <int,int> > c = make_pair( make_pair( min( plemiona[a].first.first, plemiona[b].first.first ), max( plemiona[a].first.second, plemiona[b].first.second )), make_pair( min( plemiona[a].second.first, plemiona[b].second.first ), max( plemiona[a].second.second, plemiona[b].second.second )) ); a = find(a); b = find(b); parent[a] = b; plemiona[ b ] = c; add_tree( 1, plemiona[b].first.first * 2 + 1, plemiona[ b ].first.second * 2 , 1, 2000000, make_pair( make_pair( plemiona[b].second.first * 2 + 1, plemiona[b].second.second * 2 ), b )); } int main(){ scanf("%d",&n); for (int i = 1; i <= n; i++){ parent[i] = i; int x1,x2,y1,y2; scanf("%d%d%d%d",&x1,&x2,&y1,&y2); plemiona[i] = make_pair( make_pair(x1,x2), make_pair(y1,y2)); add_tree( 1, 2*x1+1, 2*x2, 1, 2000000, make_pair( make_pair(2*y1+1,2*y2), i )); } for (int i = 1; i <= n; i++){ parent[i] = find(i); if (parent[i] == i){ result.push_back( plemiona[i] ); } } sort ( result.begin(), result.end() ); printf("%d\n", result.size()); for (int i = 0; i < result.size(); i++){ printf("%d %d %d %d\n", result[i].first.first, result[i].first.second, result[i].second.first, result[i].second.second); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | #include <cstdio> #include <vector> #include <set> #include <algorithm> using namespace std; int parent[ 100005 ], n; pair < pair <int,int> , pair <int,int> > plemiona[ 100005 ]; set < pair < pair <int,int>, int > > drzewo[ 8000005 ], drzewo2[ 8000005 ]; vector < pair < pair <int,int> , pair <int,int> > > result; void erase_tree(int pos, int s, int e, int cs, int ce, pair < pair <int,int>, int > v); bool add_tree(int pos, int s, int e, int cs, int ce, pair < pair <int,int>, int > v ); int find( int a ); void _union(int a, int b); void erase_tree(int pos, int s, int e, int cs, int ce, pair < pair <int,int>, int > v){ if (drzewo2[ pos ].find( v ) != drzewo2[ pos ].end()){ drzewo2[ pos ].erase( v ); } if ((s == cs) && (e == ce)){ if (drzewo[ pos ].find( v ) != drzewo[ pos ].end()){ drzewo[ pos ].erase( v ); } } else if ((s <= (cs+ce)/2) && (e <= (cs+ce)/2)){ erase_tree( pos*2, s, e, cs, (cs+ce)/2, v); } else if ((s > (cs+ce)/2) && (e > (cs+ce)/2)){ erase_tree( pos*2+1, s, e, (cs+ce)/2+1, ce, v); } else { erase_tree( pos*2, s, (cs+ce)/2, cs, (cs+ce)/2, v); erase_tree( pos*2+1, (cs+ce)/2+1, e, (cs+ce)/2+1, ce, v); } } bool add_tree(int pos, int s, int e, int cs, int ce, pair < pair <int,int>, int > v ){ set < pair < pair <int,int>, int > >::iterator it = drzewo[ pos ].upper_bound( make_pair( make_pair( v.first.first, -1), -1 )); if ((it != drzewo[pos].end()) && ((*it).first.first <= v.first.second)){ _union( v.second, (*it).second ); return true; } else { if (it != drzewo[pos].begin()){ it--; if ((it != drzewo[pos].end()) && (v.first.first <= (*it).first.second)){ _union( v.second, (*it).second ); return true; } } } if ((s == cs) && (e == ce)){ drzewo[ pos ].insert( v ); set < pair < pair <int,int>, int > >::iterator it = drzewo2[ pos ].upper_bound( make_pair( make_pair( v.first.first, -1), -1 )); if ((it != drzewo2[pos].end()) && ((*it).first.first <= v.first.second)){ _union( v.second, (*it).second ); return true; } else { if (it != drzewo2[pos].begin()){ it--; if ((it != drzewo2[pos].end()) && (v.first.first <= (*it).first.second)){ _union( v.second, (*it).second ); return true; } } } } else if ((s <= (cs+ce)/2) && (e <= (cs+ce)/2)){ drzewo2[ pos ].insert( v ); add_tree(pos*2, s, e, cs, (cs+ce)/2, v); } else if ((s > (cs+ce)/2) && (e > (cs+ce)/2)){ drzewo2[ pos ].insert( v ); add_tree(pos*2+1, s, e, (cs+ce)/2+1, ce, v); } else { drzewo2[ pos ].insert( v ); bool t = add_tree(pos*2, s, (cs+ce)/2, cs, (cs+ce)/2, v); if (t) return true; add_tree(pos*2+1, (cs+ce)/2+1, e, (cs+ce)/2+1, ce, v); } return false; } int find( int a ){ if (parent[a] == a){ return a; } else { parent[a] = find( parent[a] ); return parent[a]; } } void _union(int a, int b){ //printf("%d %d %d %d %d %d %d %d\n", plemiona[3].first.first, plemiona[3].first.second, plemiona[3].second.first, plemiona[3].second.second, plemiona[5].first.first, plemiona[5].first.second, plemiona[5].second.first, plemiona[5].second.second); erase_tree( 1, plemiona[a].first.first * 2 + 1, plemiona[ a ].first.second * 2 , 1, 2000000, make_pair( make_pair( plemiona[a].second.first * 2 + 1, plemiona[a].second.second * 2 ), a )); erase_tree( 1, plemiona[b].first.first * 2 + 1, plemiona[ b ].first.second * 2 , 1, 2000000, make_pair( make_pair( plemiona[b].second.first * 2 + 1, plemiona[b].second.second * 2 ), b )); pair < pair <int,int> , pair <int,int> > c = make_pair( make_pair( min( plemiona[a].first.first, plemiona[b].first.first ), max( plemiona[a].first.second, plemiona[b].first.second )), make_pair( min( plemiona[a].second.first, plemiona[b].second.first ), max( plemiona[a].second.second, plemiona[b].second.second )) ); a = find(a); b = find(b); parent[a] = b; plemiona[ b ] = c; add_tree( 1, plemiona[b].first.first * 2 + 1, plemiona[ b ].first.second * 2 , 1, 2000000, make_pair( make_pair( plemiona[b].second.first * 2 + 1, plemiona[b].second.second * 2 ), b )); } int main(){ scanf("%d",&n); for (int i = 1; i <= n; i++){ parent[i] = i; int x1,x2,y1,y2; scanf("%d%d%d%d",&x1,&x2,&y1,&y2); plemiona[i] = make_pair( make_pair(x1,x2), make_pair(y1,y2)); add_tree( 1, 2*x1+1, 2*x2, 1, 2000000, make_pair( make_pair(2*y1+1,2*y2), i )); } for (int i = 1; i <= n; i++){ parent[i] = find(i); if (parent[i] == i){ result.push_back( plemiona[i] ); } } sort ( result.begin(), result.end() ); printf("%d\n", result.size()); for (int i = 0; i < result.size(); i++){ printf("%d %d %d %d\n", result[i].first.first, result[i].first.second, result[i].second.first, result[i].second.second); } } |