#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); } } |
English