bzoj1018: [SHOI2008]堵塞的交通traffic

先表示:这道题为了减少思维复杂度,牺牲了时间

我们一开始考虑线段树,维护一个矩形内四个角的联通情况4*(4-1)/2共6种

合并两个矩形应该经过30秒思考可以想出来

但是如果直接用的话随手被卡:

因为矩形只有两层,我们枚举两点联通的每一种情况

我们考虑如果两个点在同一侧:

有:

1.直接连接

2.绕一个弯连接*2

3.绕两个弯

两点异测也是这三种情况:

那么我们可已通过两种查询概括所有情况:
1.Q(p)查询p位置上下两点是否联通

2.Q1(x1,y1,x2,y2)查询在区间[x1,x2]内是否联通

总结一下三种情况具体实现

若两点x相同但y不相同,则称两点互为对偶点

1.直接连接:Q1(x1,y1,x2,y2)

2.一个弯:Q1(p1,p2的对偶点) && Q(p2)

3两个弯:Q1(p1对偶点,p2对偶点) && Q(p1) && Q(p2)

下面是代码:

  1 #include<cstdio>
  2 #include<algorithm>
  3 using namespace std ; 
  4 
  5 const int MAXN = 1024 * 128 + 20 ;
  6 int N ;
  7 
  8 int C [ MAXN * 2 ] [ 2 ] [ 2 ] ;
  9 int S [ MAXN * 2 ] [ 2 ] ;
 10 int c [ MAXN ] [ 2 ] ;
 11 int l [ MAXN ] ;
 12 
 13 void maintain_1 ( const int o , const int p ) {
 14     C [ o ] [ 0 ] [ 0 ] = c [ p ] [ 0 ] ;
 15     C [ o ] [ 1 ] [ 1 ] = c [ p ] [ 1 ] ;
 16     S [ o ] [ 0 ] = l [ p ] ;
 17     C [ o ] [ 1 ] [ 0 ] = l [ p ] && c [ p ] [ 0 ] ;
 18     C [ o ] [ 0 ] [ 1 ] = l [ p ] && c [ p ] [ 1 ] ;
 19     S [ o ] [ 1 ] = l [ p ] && c [ p ] [ 0 ] && c [ p ] [ 1 ] ;
 20 }
 21 
 22 void maintain_2 ( int ( * o ) [ 2 ] , const int ( * o1 ) [ 2 ] , const int ( * o2 ) [ 2 ] ) {
 23     #define D(a,b) o[a][b] = (o1[a][0]&&o2[0][b]) || (o1[a][1]&&o2[1][b])
 24     D(1,1);D(1,0);D(0,0);D(0,1);
 25     #undef D
 26 }
 27 
 28 void maintain_3 ( int & o , const int * o1 , const int * o2 , const int ( * c ) [ 2 ] ) {
 29     o = o1 [ 0 ] || ( o2 [ 0 ] && c [ 0 ] [ 0 ] && c [ 1 ] [ 1 ] ) ;
 30 }
 31 
 32 void maintain_4 ( int & o , const int * o1 , const int * o2 , const int ( * c ) [ 2 ] ) {
 33     o = o2 [ 1 ] || ( o1 [ 1 ] && c [ 0 ] [ 0 ] && c [ 1 ] [ 1 ] ) ;
 34 }
 35 
 36 void modify ( const int p , const int opt , const int v ) {
 37     if ( opt < 2 ) c [ p ] [ opt ] = v ;
 38     else l [ p ] = v ;
 39 }
 40     
 41 int translate ( const int x1 , const int y1 , const int x2 , const int y2 ) {
 42     if ( x1 != x2 ) return y1 - 1 ; 
 43     else return 2 ;
 44 }
 45 
 46 static struct {
 47     int p ;
 48     void W ( const int o , const int L , const int R ) {
 49         if ( R - L == 1 ) maintain_1 ( o , L ) ;
 50         else {
 51             const int M = ( L + R ) >> 1 ;
 52             if ( p < M ) W ( o << 1 , L , M ) ;
 53             else W ( o << 1 | 1 , M , R ) ;
 54             maintain_2 ( C [ o ] , C [ o << 1 ] , C [ o << 1 | 1 ] ) ;
 55             maintain_3 ( S [ o ] [ 0 ] , S [ o << 1 ] , S [ o << 1 | 1 ] , C [ o << 1 ] ) ;
 56             maintain_4 ( S [ o ] [ 1 ] , S [ o << 1 ] , S [ o << 1 | 1 ] , C [ o << 1 | 1 ] ) ;  
 57         }
 58     }
 59     void operator () ( const int P ) {
 60         p = P ;
 61         W ( 1 , 1 , N + 1 ) ;
 62     }
 63 } maintain ;
 64 
 65 typedef int ( * la ) [ 2 ] ;
 66 
 67 static struct {
 68     int l , r ;
 69     la W ( const int o , const int L , const int R ) {
 70         la a = 0 ;
 71         if ( l <= L && R <= r ) {
 72             a = new (int[2][2]);
 73             #define D(c,d) a[c][d]=C[o][c][d] 
 74             D(0,0);D(0,1);D(1,0);D(1,1);
 75             #undef D 
 76         } else {
 77             const int M = ( L + R ) >> 1 ; 
 78             la a1 = ( l < M ) ? W ( o << 1 , L , M ) : 0 ;
 79             la a2 = ( M < r ) ? W ( o << 1 | 1 , M , R ) : 0 ;
 80             if ( l < M && M < r ) {
 81                 a = new (int [2][2]) ;
 82                 maintain_2 ( a , a1 , a2 ) ;
 83                 delete a1 ; delete a2 ;
 84             } else {
 85                 a = a1 ? a1 : a2 ;
 86             }
 87         }
 88         return a ;
 89     }
 90     bool operator ( ) ( int x1 , int y1 , int x2 , int y2 ) {
 91         if ( x1 == x2 ) return y1 == y2 ;
 92         if ( x2 < x1 ) swap ( x1 , x2 ) , swap ( y1 , y2 ) ;
 93         l = x1 ; r = x2 ; 
 94         la a = W ( 1 , 1 , N + 1 ) ;
 95         bool b = a [ y1 ] [ y2 ] ;
 96         delete a ;
 97         return b ;
 98     }
 99 } Q1 ;
100 
101 static struct {
102     int p ;
103     typedef pair < int , int > Pair ;
104     Pair W ( const int o , const int L , const int R ) {
105         if ( L == p ) return Pair ( S [ o ] [ 0 ] , C [ o ] [ 1 ] [ 1 ] && C [ o ] [ 0 ] [ 0 ] ) ;
106         else {
107             const int M = ( L + R ) >> 1 ;
108             Pair a1 ;
109             if ( p < M ) {
110                 a1 = W ( o << 1 , L , M ) ;
111                 return Pair ( a1 . first || ( a1 . second && S [ o << 1 | 1 ] [ 0 ] ) ,
112                             a1 . second && C [ o << 1 | 1 ] [ 0 ] [ 0 ] && C [ o << 1 | 1 ] [ 1 ] [ 1 ] ) ;
113             } else {
114                 return W ( o << 1 | 1 , M , R ) ;
115             }
116         }
117     }
118     bool operator ( ) ( const int P ) {
119         p = P ;
120         return W ( 1 , 1 , N + 1 ) . first ;
121     }
122 } Q2 ;
123 
124 static struct {
125     int p ;
126     typedef pair < int , int > Pair ;
127     Pair W ( const int o , const int L , const int R ) {
128         if ( R - 1 == p ) return Pair ( S [ o ] [ 1 ] , C [ o ] [ 1 ] [ 1 ] && C [ o ] [ 0 ] [ 0 ] ) ;
129         else {
130             const int M = ( L + R ) >> 1 ;
131             Pair a1 ;
132             if ( M <= p ) {
133                 a1 = W ( o << 1 | 1 , M , R ) ;
134                 return Pair ( a1 . first || ( a1 . second && S [ o << 1 ] [ 1 ] ) ,
135                         a1 . second && C [ o << 1 ] [ 0 ] [ 0 ] && C [ o << 1 ] [ 1 ] [ 1 ] ) ;
136             } else {
137                 return W ( o << 1 , L , M ) ;
138             }
139         }
140     }
141     bool operator ( ) ( const int P ) {
142         if ( P == 1 ) return false ;
143         p = P - 1 ;
144         return W ( 1 , 1 , N + 1 ) . first ;
145     }
146 } Q3 ;
147 
148 bool Q ( int p ) {
149     return Q2 ( p ) || Q3 ( p ) ;
150 }
151 
152 bool Q ( int x1 , int y1 , int x2 , int y2 ) {
153     if ( x2 < x1 ) swap ( x1 , x2 ) , swap ( y1 , y2 ) ;
154     y1 -= 1 ; y2 -= 1 ;
155     return Q1 ( x1 , y1 , x2 , y2 ) ||
156     ( Q1 ( x1 , y1 ^ 1 , x2 , y2 ) && Q ( x1 ) ) ||
157     ( Q1 ( x1 , y1 , x2 , y2 ^ 1 ) && Q ( x2 ) ) ||
158     ( Q1 ( x1 , y1 ^ 1 , x2 , y2 ^ 1 ) && Q ( x1 ) && Q ( x2 ) ) ;
159 }
160 
161 #ifdef DEBUG1
162 char opt [ 20 ] ;
163 int size ;
164 int main () {
165     scanf ( "%d" , & size ) ; N = size + 2 ; 
166     while ( scanf ( "%s" , opt ) , opt [ 0 ] != 'E' ) {
167         int x1 , x2, y1 , y2 ;
168         scanf ( "%d%d%d%d" , & x1 , & y1, & x2 , & y2 ) ;
169         const int W = min ( x1 , x2 ) ;
170         const int O = translate ( x1 , y1 , x2 , y2 ) ;
171         switch ( opt [ 0 ] ) {
172             case 'O' : 
173                 modify ( W , O , 1 ) ;
174                 maintain ( W ) ;
175                 break ;
176             case 'C' :
177                 modify ( W , O , 0 ) ;
178                 maintain ( W ) ;
179                 break ;
180             case 'Q' :
181                 puts ( Q1 ( x1 , y1 , x2 , y2 ) ? "YES" : "NO" ) ;
182                 break ;
183             case 'W' : 
184                 puts ( Q2 ( x1 ) ? "YES" : "NO" ) ;
185                 puts ( Q3 ( x1 ) ? "YES" : "NO" ) ;
186             break ;
187         }
188     }
189     return 0 ;
190 }
191 #else
192 char opt [ 20 ] ;
193 int size ;
194 int main () {
195     scanf ( "%d" , & size ) ; N = size + 2 ; 
196     while ( scanf ( "%s" , opt ) , opt [ 0 ] != 'E' ) {
197         int x1 , x2, y1 , y2 ;
198         scanf ( "%d%d%d%d" , & y1 , & x1, & y2 , & x2 ) ;
199         const int W = min ( x1 , x2 ) ;
200         const int O = translate ( x1 , y1 , x2 , y2 ) ;
201         switch ( opt [ 0 ] ) {
202             case 'O' : 
203                 modify ( W , O , 1 ) ;
204                 maintain ( W ) ;
205                 break ;
206             case 'C' :
207                 modify ( W , O , 0 ) ;
208                 maintain ( W ) ;
209                 break ;
210             case 'A' :
211                 puts ( Q ( x1 , y1 , x2 , y2 ) ? "Y" : "N" ) ;
212                 break ;
213         }
214     }
215     return 0 ;
216 }
217 #endif

 

posted @ 2016-01-15 18:40  Chris_2  阅读(...)  评论(... 编辑 收藏