bzoj 1018 线段树维护连通性
2015-02-21 22:14
246 查看
本题将一道LCT的题特殊化(支持加边和删边,询问图的连通性),将图变成了2×m的网格图,然后就神奇地可以用线段树来维护。
对于每个区间[l,r],维护其四个角落之间的连通性(仅仅通过[l,r]这段的边构建起的连通性)。
查询[l,r]时,先计算出[1,l-1],[l,r],[r+1,c]这三个线段的连通性,然后将[l,r]的四个角变成并查集的4个点,先用[l,r]中的6种关系更新,在看是否可以从左上角的点通过左边区间绕道左下角,以及从右上角通过右边区间绕道右下角,该并的并起来后直接看查询的点是否在一个集合即可。
View Code
对于每个区间[l,r],维护其四个角落之间的连通性(仅仅通过[l,r]这段的边构建起的连通性)。
查询[l,r]时,先计算出[1,l-1],[l,r],[r+1,c]这三个线段的连通性,然后将[l,r]的四个角变成并查集的4个点,先用[l,r]中的6种关系更新,在看是否可以从左上角的点通过左边区间绕道左下角,以及从右上角通过右边区间绕道右下角,该并的并起来后直接看查询的点是否在一个集合即可。
/************************************************************** Problem: 1018 User: idy002 Language: C++ Result: Accepted Time:1472 ms Memory:2840 kb ****************************************************************/ #include <cstdio> #include <iostream> #define maxn 100010 #define AB 1 #define AC 2 #define AD 4 #define BC 8 #define BD 16 #define CD 32 using namespace std; // a b // c d typedef unsigned Stat; Stat stat[maxn]; int son[maxn][2], ntot, root; int c; bool er[3][maxn], ed[maxn]; Stat merge( Stat l, Stat r, int mid ) { Stat ab = ((l&AB)&&(r&AB)&&er[1][mid]) || ((l&AD)&&(r&BC)&&er[2][mid]) ? AB : 0; Stat cd = ((l&CD)&&(r&CD)&&er[2][mid]) || ((l&BC)&&(r&AD)&&er[1][mid]) ? CD : 0; Stat ad = ((l&AB)&&(r&AD)&&er[1][mid]) || ((l&AD)&&(r&CD)&&er[2][mid]) ? AD : 0; Stat bc = ((l&CD)&&(r&BC)&&er[2][mid]) || ((l&BC)&&(r&AB)&&er[1][mid]) ? BC : 0; Stat ac = (l&AC) || ((l&AB)&&(l&CD)&&(er[1][mid])&&(er[2][mid])&&(r&AC)) ? AC : 0; Stat bd = (r&BD) || ((r&AB)&&(r&CD)&&(er[1][mid])&&(er[2][mid])&&(l&BD)) ? BD : 0; return ab | ac | ad | bc | bd | cd; } void update( int nd, int lf, int rg ) { stat[nd] = merge( stat[son[nd][0]], stat[son[nd][1]], (lf+rg)>>1 ); } int build( int lf, int rg ) { if( lf>rg ) return 0; int nd = ++ntot; if( lf==rg ) { stat[nd] = AB | CD; return nd; } int mid = (lf+rg)>>1; son[nd][0] = build( lf, mid ); son[nd][1] = build( mid+1, rg ); update( nd, lf, rg ); return nd; } void modify( int x, int nd, int lf, int rg ) { if( lf==rg ) { stat[nd] = AB | CD; if( ed[lf] ) stat[nd] |= AC | BD | AD | BC; return; } int mid = (lf+rg)>>1; if( x<=mid ) modify(x,son[nd][0],lf,mid); else modify(x,son[nd][1],mid+1,rg); update(nd,lf,rg); } Stat query( int L, int R, int nd, int lf, int rg ) { if( L<=lf&&rg<=R ) return stat[nd]; int mid = (lf+rg)>>1; if( R<=mid ) return query( L, R, son[nd][0], lf, mid ); if( L>mid ) return query( L, R, son[nd][1], mid+1, rg ); Stat lstat = query( L, R, son[nd][0], lf, mid ); Stat rstat = query( L, R, son[nd][1], mid+1, rg ); return merge(lstat,rstat,mid); } int fa[5]; void init() { for( int i=1; i<=4; i++ ) fa[i]=i; } int find( int i ) { return fa[i]==i ? i : fa[i]=find(fa[i]); } void unon( int a, int b ) { a = find(a); b = find(b); fa[a] = b; } int main() { scanf( "%d", &c ); root = build( 1, c ); while(1) { char ch[10]; scanf( "%s", ch ); if( ch[0]=='E' ) return 0; int ax, ay, bx, by; scanf( "%d%d%d%d", &ax, &ay, &bx, &by ); if( ch[0]=='A' ) { if( ay>by ) { swap( ax, bx ); swap( ay, by ); } Stat sl=0, sc=0, sr=0; if( ay>1 ) sl = query(1,ay-1,root,1,c); sc = query(ay,by,root,1,c); if( by<c ) sr = query(by+1,c,root,1,c); init(); if( sc&AB ) unon( 1, 2 ); if( sc&AC ) unon( 1, 3 ); if( sc&AD ) unon( 1, 4 ); if( sc&BC ) unon( 2, 3 ); if( sc&BD ) unon( 2, 4 ); if( sc&CD ) unon( 3, 4 ); if( (sl&BD) && er[1][ay-1] && er[2][ay-1] ) unon( 1, 3 ); if( (sr&AC) && er[1][by] && er[2][by] ) unon( 2, 4 ); bool ok = false; if( ax==1 && bx==1 ) { ok = find( 1 ) == find( 2 ); } else if( ax==1 && bx==2 ) { ok = find( 1 ) == find( 4 ); } else if( ax==2 && bx==1 ) { ok = find( 3 ) == find( 2 ); } else if( ax==2 && bx==2 ) { ok = find( 3 ) == find( 4 ); } printf( "%s\n", ok ? "Y" : "N" ); } else { bool *p; if( ax==bx ) { p = &er[ax][min(ay,by)]; } else { p = &ed[ay]; } *p = ch[0]=='O'; modify( ay, root, 1, c ); if( ay!=by ) modify( by, root, 1, c ); } } }
View Code
相关文章推荐
- [BZOJ1018][SHOI2008]堵塞的交通traffic(线段树维护连通性)
- BZOJ.1018.[SHOI2008]堵塞的交通(线段树维护连通性)
- bzoj 1018: [SHOI2008]堵塞的交通traffic (线段树维护连通性)
- 【bzoj1018】[SHOI2008]堵塞的交通traffic 线段树维护连通性
- bzoj 1018 堵塞的交通|线段树维护连通性
- BZOJ 1018 线段树维护连通性
- BZOJ 1018 线段树维护图的连通性问题
- 【bzoj1018】 堵塞的交通 线段树维护连通性
- [BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】
- 【BZOJ1018】堵塞的交通traffic(线段树,网格图,连通性)
- [BZOJ 3995] [SDOI2015] 道路修建 【线段树维护连通性】
- [BZOJ1018][SHOI2008]堵塞的交通traffic 线段树维护连通性
- BZOJ[1018][SHOI2008]堵塞的交通traffic 线段树
- [BZOJ1018][SHOI2008]堵塞的交通traffic(线段树)
- BZOJ 1099([POI2007]树Drz-9次线段树&分类讨论+线段树与插入顺序维护2个参数)
- BZOJ_1018_[SHOI2008]_交通堵塞traffic_(线段树)
- 【BZOJ1018】堵塞的交通(线段树)
- BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树模板
- bzoj1018: [SHOI2008]堵塞的交通traffic 线段树区间合并
- 【BZOJ1798】[Ahoi2009]Seq 维护序列seq 【线段树】