# bzoj 1018 线段树维护连通性

  1 /**************************************************************
2     Problem: 1018
3     User: idy002
4     Language: C++
5     Result: Accepted
6     Time:1472 ms
7     Memory:2840 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #include <iostream>
12 #define maxn 100010
13 #define AB 1
14 #define AC 2
16 #define BC 8
17 #define BD 16
18 #define CD 32
19 using namespace std;
20
21 // a b
22 // c d
23
24 typedef unsigned Stat;
25
26 Stat stat[maxn];
27 int son[maxn][2], ntot, root;
28
29 int c;
30 bool er[3][maxn], ed[maxn];
31
32 Stat merge( Stat l, Stat r, int mid ) {
33     Stat ab = ((l&AB)&&(r&AB)&&er[1][mid]) || ((l&AD)&&(r&BC)&&er[2][mid]) ? AB : 0;
34     Stat cd = ((l&CD)&&(r&CD)&&er[2][mid]) || ((l&BC)&&(r&AD)&&er[1][mid]) ? CD : 0;
36     Stat bc = ((l&CD)&&(r&BC)&&er[2][mid]) || ((l&BC)&&(r&AB)&&er[1][mid]) ? BC : 0;
37     Stat ac = (l&AC) || ((l&AB)&&(l&CD)&&(er[1][mid])&&(er[2][mid])&&(r&AC)) ? AC : 0;
38     Stat bd = (r&BD) || ((r&AB)&&(r&CD)&&(er[1][mid])&&(er[2][mid])&&(l&BD)) ? BD : 0;
39     return ab | ac | ad | bc | bd | cd;
40 }
41 void update( int nd, int lf, int rg ) {
42     stat[nd] = merge( stat[son[nd][0]], stat[son[nd][1]], (lf+rg)>>1 );
43 }
44 int build( int lf, int rg ) {
45     if( lf>rg ) return 0;
46     int nd = ++ntot;
47     if( lf==rg ) {
48         stat[nd] = AB | CD;
49         return nd;
50     }
51     int mid = (lf+rg)>>1;
52     son[nd][0] = build( lf, mid );
53     son[nd][1] = build( mid+1, rg );
54     update( nd, lf, rg );
55     return nd;
56 }
57 void modify( int x, int nd, int lf, int rg ) {
58     if( lf==rg ) {
59         stat[nd] = AB | CD;
60         if( ed[lf] )
61             stat[nd] |= AC | BD | AD | BC;
62         return;
63     }
64     int mid = (lf+rg)>>1;
65     if( x<=mid ) modify(x,son[nd][0],lf,mid);
66     else modify(x,son[nd][1],mid+1,rg);
67     update(nd,lf,rg);
68 }
69 Stat query( int L, int R, int nd, int lf, int rg ) {
70     if( L<=lf&&rg<=R ) return stat[nd];
71     int mid = (lf+rg)>>1;
72     if( R<=mid ) return query( L, R, son[nd][0], lf, mid );
73     if( L>mid ) return query( L, R, son[nd][1], mid+1, rg );
74     Stat lstat = query( L, R, son[nd][0], lf, mid );
75     Stat rstat = query( L, R, son[nd][1], mid+1, rg );
76     return merge(lstat,rstat,mid);
77 }
78
79 int fa[5];
80 void init() {
81     for( int i=1; i<=4; i++ ) fa[i]=i;
82 }
83 int find( int i ) {
84     return fa[i]==i ? i : fa[i]=find(fa[i]);
85 }
86 void unon( int a, int b ) {
87     a = find(a);
88     b = find(b);
89     fa[a] = b;
90 }
91 int main() {
92     scanf( "%d", &c );
93     root = build( 1, c );
94     while(1) {
95         char ch[10];
96
97         scanf( "%s", ch );
98         if( ch[0]=='E' ) return 0;
99         int ax, ay, bx, by;
100         scanf( "%d%d%d%d", &ax, &ay, &bx, &by );
101
102         if( ch[0]=='A' ) {
103             if( ay>by ) {
104                 swap( ax, bx );
105                 swap( ay, by );
106             }
107             Stat sl=0, sc=0, sr=0;
108             if( ay>1 ) sl = query(1,ay-1,root,1,c);
109             sc = query(ay,by,root,1,c);
110             if( by<c ) sr = query(by+1,c,root,1,c);
111
112             init();
113             if( sc&AB ) unon( 1, 2 );
114             if( sc&AC ) unon( 1, 3 );
115             if( sc&AD ) unon( 1, 4 );
116             if( sc&BC ) unon( 2, 3 );
117             if( sc&BD ) unon( 2, 4 );
118             if( sc&CD ) unon( 3, 4 );
119             if( (sl&BD) && er[1][ay-1] && er[2][ay-1] ) unon( 1, 3 );
120             if( (sr&AC) && er[1][by]   && er[2][by]   ) unon( 2, 4 );
121
122             bool ok = false;
123             if( ax==1 && bx==1 ) {
124                 ok = find( 1 ) == find( 2 );
125             } else if( ax==1 && bx==2 ) {
126                 ok = find( 1 ) == find( 4 );
127             } else if( ax==2 && bx==1 ) {
128                 ok = find( 3 ) == find( 2 );
129             } else if( ax==2 && bx==2 ) {
130                 ok = find( 3 ) == find( 4 );
131             }
132
133             printf( "%s\n", ok ? "Y" : "N" );
134         } else {
135             bool *p;
136             if( ax==bx ) {
137                 p = &er[ax][min(ay,by)];
138             } else {
139                 p = &ed[ay];
140             }
141             *p = ch[0]=='O';
142             modify( ay, root, 1, c );
143             if( ay!=by )
144                 modify( by, root, 1, c );
145         }
146     }
147 }
View Code

posted @ 2015-02-21 22:14  idy002  阅读(...)  评论(... 编辑 收藏