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