sicily 1876 && 1949 不相交集+线段树

//不相交集+线段树 //输入 s[1..n] //输入 si,ei s[si..ei]之间最小值与最大值无向连通 //一开始以为直接 si ei连起。。悲剧 //找段最小值最大值用线段树 貌似比较慢 //不相交集用树 #include <iostream> #include <cstdio> #define mx 100001 #define __mx(a,b) (a>b)?a:b #define __mn(a,b) (a>b)?b:a using namespace std; int n,s[mx],v,a,b; int c; struct Seq { int _mx,_mn; int x,y; }seq[4*mx]; void buildTree( int p,int x,int y ) { seq[p].x = x; seq[p].y = y; if( x == y ) { seq[p]._mx = seq[p]._mn = s[x]; return ; } int mid = (x + y)/2; buildTree( 2*p,x,mid); buildTree( 2*p+1,mid+1,y); seq[p]._mx = __mx( seq[2*p]._mx,seq[2*p+1]._mx ); seq[p]._mn = __mn( seq[2*p]._mn,seq[2*p+1]._mn ); } void findseq( int p,int x,int y,int &a,int &b ) //引用a b 跑一趟查找 { if( seq[p].x == x && seq[p].y == y ) { a = seq[p]._mn; b = seq[p]._mx; return ; } int mid = ( seq[p].x + seq[p].y ) / 2; if( mid >= y ) { findseq( 2*p,x,y,a,b ); return ; } if( mid < x ) { findseq( 2*p+1,x,y,a,b ); return; } int a1,a2,b1,b2; findseq( 2*p,x,mid,a1,b1 ); findseq( 2*p+1,mid+1,y,a2,b2 ); a = (( a1 < a2 ) ? a1:a2); b = (( b1 > b2 ) ? b1:b2); } struct Node { int parent; int rank; //记录高度 高树做低的父亲 }node[mx]; inline int findp( int a ) { return ( ( a == node[a].parent ) ? a : findp(node[a].parent) ); } void u( int a,int b ) { if( a == b ) return ; if( node[a].rank > node[b].rank ) node[b].parent = a; else { node[a].parent = b; if( node[a].rank == node[b].rank ) { node[b].rank++; } } } int main() { //freopen("1.txt","r",stdin); while( scanf("%d",&n) != EOF ) { if( c++ != 0 ) cout<<endl; cout<<"CASE "<<c<<endl; for( int i = 1;i <= n;i++ ) { node[i].parent = i;node[i].rank = 0; scanf( "%d",s+i ); } buildTree( 1,1,n ); scanf("%d",&v); while( v-- ) { scanf( "%d%d",&a,&b ); int _mn,_mx; findseq( 1,a,b,_mn,_mx ); u( findp( _mn ),findp( _mx ) ); } scanf("%d",&v); while( v-- ) { scanf( "%d%d",&a,&b ); if( findp(a) == findp(b) ) cout<<"YES"<<endl; else cout<<"NO"<<endl; } } return 0; }

你可能感兴趣的:(c,struct)