感觉还是上海人出题水平高?这套题写得心旷神怡的。。。总之很难就是啦

由于我实在不适应博客园这种排版和字体。。所以我的文章可能会特别难看大家见谅。。说不定回头开发一个支持全局LaTeX的博客也不错?2333

BZOJ1018 堵塞的交通:

题目大意:有一个2*n的矩阵,初始时没有边,每次可能会打通两个相邻的节点(相邻指曼哈顿距离为1)之间的无向道路或是拆毁两个相邻节点的道路,每次询问两个节点是否连通。

神奇的做法:使用动态树维护整个图的连通性!(这真的可写么?)

正确的做法:由于只有两排,使用一个线段树来维护连通性就可以了。。思路就是线段树的每个叶子节点维护四个节点的C字形的连通性,每个非叶子节点维护这一段的四个顶点的C字型(每个线段树节点其实是一个并查集) 虽然连接方式有很多种情况,但毕竟是有限的几种,手工特判一下就好了。。细节挺多的。特别要注意从两边联通这种情况。随便写一写就好了。

  1 //date 20140624
  2 #include <cstdio>
  3 #include <cstring>
  4  
  5 const int maxn = 105000;
  6  
  7 inline int getint()
  8 {
  9     int ans(0); char w = getchar();
 10     while(w < '0' || '9' < w) w = getchar();
 11     while('0' <= w && w <= '9'){ans = ans * 10 + w - '0'; w = getchar();}
 12     return ans;
 13 }
 14  
 15 template <typename T> inline void swap(T &a, T &b){T x = a; a = b; b = x;}
 16  
 17 /*
 18 0---------2
 19 |         |
 20 |         |
 21 |         |
 22 1---------3
 23 */
 24 int tmp[10];
 25 struct info
 26 {
 27     int num[4];
 28     info(){}
 29     info(int a, int b, int c, int d){num[0] = a; num[1] = b; num[2] = c; num[3] = d;}
 30     void std()
 31     {
 32         memset(tmp, 0, sizeof tmp); int count = 0;
 33         for(int i = 0; i < 4; ++i) if(!tmp[num[i]]) tmp[num[i]] = ++count;
 34         for(int i = 0; i < 4; ++i) num[i] = tmp[num[i]];
 35     }
 36 };
 37  
 38 struct DSU
 39 {
 40     int p[7];
 41     void preset(){  for(int i = 1; i <= 6; ++i) p[i] = i;}
 42     DSU(){preset();}
 43     int getp(int x){return p[x] == x ? x : (p[x] = getp(p[x]));}
 44     void merge(int x, int y){if((x = getp(x)) != (y = getp(y))) p[x] = y;}
 45 };
 46  
 47 inline info operator+ (info A, info B)
 48 {
 49     DSU MEOW;
 50     for(int i = 0; i < 3; ++i) for(int j = i + 1; j < 4; ++j) 
 51         if(A.num[i] == A.num[j]) MEOW.merge(i + 1, j + 1);
 52     for(int i = 0; i < 3; ++i) for(int j = i + 1; j < 4; ++j) 
 53         if(B.num[i] == B.num[j]) MEOW.merge(i + 3, j + 3);
 54     info ans(MEOW.getp(1), MEOW.getp(2), MEOW.getp(5), MEOW.getp(6)); ans.std();
 55     return ans;
 56 }
 57  
 58 int n;
 59 info wius[8];
 60 int now[maxn];
 61  
 62 inline void preset()
 63 {
 64     wius[0] = info(1, 2, 3, 4);
 65     wius[1] = info(1, 2, 1, 3);
 66     wius[2] = info(1, 1, 2, 3);
 67     wius[3] = info(1, 1, 1, 2);
 68     wius[4] = info(1, 2, 3, 2);
 69     wius[5] = info(1, 2, 1, 2);
 70     wius[6] = info(1, 1, 2, 1);
 71     wius[7] = info(1, 1, 1, 1);
 72 }
 73  
 74  
 75 struct zkw_sget
 76 {
 77     int base; info data[300000];
 78     void preset()
 79     {
 80         for(base = 1; base < n + 2; base <<= 1);
 81         for(int i = 1; i < (base << 1); ++i) data[i] = wius[0];
 82     }
 83      
 84     void change(int pos, int val)
 85     {
 86         data[pos + base] = wius[now[pos] = val];
 87         for(int i = (pos + base) >> 1; i; i >>= 1) data[i] = data[i << 1] + data[(i << 1) | 1];
 88     }
 89      
 90     info mini_query(int l, int r)
 91     {
 92         info ansl(wius[5]), ansr(wius[5]);
 93         for(l = l + base - 1, r = r + base + 1; l < r - 1; l >>= 1, r >>= 1)
 94         {
 95             if(!(l & 1)) ansl = ansl + data[l ^ 1];
 96             if( (r & 1)) ansr = data[r ^ 1] + ansr;
 97         }
 98         return ansl + ansr;
 99     }
100      
101     info query(int l, int r)
102     {
103         info ansl, ansm, ansr;
104         ansl = mini_query(1, l - 1);
105         ansm = mini_query(l, r - 1);
106         ansr = mini_query(r, n);
107         if(ansl.num[2] == ansl.num[3]) ansm = wius[7] + ansm;
108         if(ansr.num[0] == ansr.num[1]) ansm = ansm + wius[7];
109         return ansm;
110     }
111 }MEOW;
112  
113 char order[10];
114  
115 int main()
116 {
117     n = getint(); preset();
118     MEOW.preset();
119     while(true)
120     {
121         scanf("%s", order);
122         int x1, y1, x2, y2;
123         switch(order[0])
124         {
125             case 'E': return 0; break;
126             case 'O':  case 'C':
127                 x1 = getint(); y1 = getint(); x2 = getint(); y2 = getint(); 
128                 if(y1 > y2){swap(x1, x2); swap(y1, y2);}
129                 if(y1 == y2) 
130                 {
131                     MEOW.change(y1, now[y1] ^ 2);
132                 }else {
133                     if(x1 == 1) MEOW.change(y1, now[y1] ^ 1);
134                     else MEOW.change(y1, now[y1] ^ 4);
135                 }
136             break;
137  
138             case 'A': 
139                 x1 = getint(); y1 = getint(); x2 = getint(); y2 = getint(); 
140                 if(y1 > y2){swap(x1, x2); swap(y1, y2);}
141                 info tmp = MEOW.query(y1, y2);
142                 printf(tmp.num[x1 - 1] == tmp.num[x2 + 1] ? "Y\n" : "N\n");
143             break;
144         }
145     }
146     return 0;
147 }
traffic

相关文章:

  • 2021-08-08
  • 2021-12-04
  • 2021-06-28
  • 2021-06-27
  • 2022-01-14
  • 2021-12-12
  • 2021-07-23
  • 2021-12-10
猜你喜欢
  • 2022-12-23
  • 2021-12-10
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2023-03-26
相关资源
相似解决方案