一定是两个障碍物组成一对来破坏连通性,每个障碍物可能属于最多3对,然后维护障碍物对数就行。但是懒得讨论,暴力分块过了。
涉及到修改的块暴力重构这个块的连通性。只要左端两个位置和右端两个位置中任意两个可互达就具有连通性。
然后每次询问,就先看每个块的连通性,再看每个块之间是否成功的连接起来。
1 #include <cstdio> 2 #include <cmath> 3 using namespace std; 4 int n,q,m,M,acc[1100],mp[3][110000]; 5 int id(int x) 6 { 7 return (x + M - 1) / M; 8 } 9 bool check() 10 { 11 for (int i = 1;i <= m;i++) 12 if (acc[i] == false) 13 return false; 14 for (int i = 1;i <= m;i++) 15 if (!((mp[1][(i - 1) * M + 1] == 1 && mp[1][(i - 1) * M] == 1) || (mp[2][(i - 1) * M + 1] == 1 && mp[2][(i - 1) * M] == 1))) 16 { 17 return false; 18 } 19 return true; 20 } 21 bool dfs(int x,int tar,int sta1,int sta2) 22 { 23 if (x == tar) 24 return true; 25 int new1 = 0,new2 = 0; 26 if (sta1 && mp[1][x + 1] == 1) 27 new1 = 1; 28 if (sta2 && mp[2][x + 1] == 1) 29 new2 = 1; 30 if ((new1 == 1 || new2 == 1) && mp[1][x + 1] == 1 && mp[2][x + 1] == 1) 31 new1 = new2 = 1; 32 if (new1 || new2) 33 return dfs(x + 1,tar,new1,new2); 34 else 35 return false; 36 } 37 void change(int x,int y) 38 { 39 mp[x][y] ^= 1; 40 if (dfs((id(y) - 1) * M,id(y) * M,1,1)) 41 acc[id(y)] = 1; 42 else 43 acc[id(y)] = 0; 44 } 45 int main() 46 { 47 scanf("%d%d",&n,&q); 48 M = sqrt(n); 49 m = id(n); 50 for (int i = 0;i <= m * M;i++) 51 mp[1][i] = mp[2][i] = 1; 52 for (int i = 1;i <= m;i++) 53 acc[i] = 1; 54 int tr,tc; 55 for (int i = 1;i <= q;i++) 56 { 57 scanf("%d%d",&tr,&tc); 58 change(tr,tc); 59 if (check()) 60 printf("Yes\n"); 61 else 62 printf("No\n"); 63 } 64 return 0; 65 }
CF1293C - NEKO's Maze Game 分块
原文地址:https://www.cnblogs.com/iat14/p/12272037.html
时间: 2024-10-10 06:56:20