description

洛谷

给出一个\(n\times n\)的黑白棋盘。

\(m\)次操作,每次将一个格子进行颜色翻转,求每次操作后的黑白四连通块数。

data range

\[n\le 200,m\le 10000
\]

solution

解决动态维护图连通性的方法有2种:

一种是通过\(LCT\)动态维护最大删边时间生成树,另一种是线段树分治。

所以当然线段树分治更好写不是吗反正不会LCT的做法。

然后稍稍讨论一波就完了

Code

  1. #include<bits/stdc++.h>
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstdlib>
  5. #include<iomanip>
  6. #include<cstring>
  7. #include<complex>
  8. #include<vector>
  9. #include<cstdio>
  10. #include<string>
  11. #include<bitset>
  12. #include<ctime>
  13. #include<cmath>
  14. #include<queue>
  15. #include<stack>
  16. #include<map>
  17. #include<set>
  18. #define F "a"
  19. #define mp make_pair
  20. #define pb push_back
  21. #define RG register
  22. #define il inline
  23. using namespace std;
  24. typedef unsigned long long ull;
  25. typedef pair<int,int> PI;
  26. typedef vector<int>VI;
  27. typedef long long ll;
  28. typedef double dd;
  29. const int N=2e2+10;
  30. const int K=4e4+10;
  31. const int mod=998244353;
  32. const int inf=2147483647;
  33. const ll INF=1ll<<60;
  34. const dd eps=1e-7;
  35. const dd pi=acos(-1);
  36. il ll read(){
  37. RG ll data=0,w=1;RG char ch=getchar();
  38. while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
  39. if(ch=='-')w=-1,ch=getchar();
  40. while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
  41. return data*w;
  42. }
  43. il void file(){
  44. freopen(F".in","r",stdin);
  45. freopen(F".out","w",stdout);
  46. }
  47. int n,m,p[N][N],cnt,c[N][N],v[N][N],b,w;VI a[N][N];bool vis[N][N];
  48. struct node{int x,y,c;}now;
  49. vector<node>M[K];
  50. #define ls (i<<1)
  51. #define rs (i<<1|1)
  52. #define mid ((l+r)>>1)
  53. void modify(int i,int l,int r,int x,int y){
  54. if(x<=l&&r<=y){M[i].push_back(now);return;}
  55. if(x<=mid)modify(ls,l,mid,x,y);
  56. if(mid<y)modify(rs,mid+1,r,x,y);
  57. }
  58. int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
  59. struct Mod{int id,u,v;};vector<Mod>cal;
  60. int nowid,top;
  61. int fa[K];
  62. int find(int x){
  63. if(!fa[x])return x;
  64. RG int ff=find(fa[x]);
  65. if(fa[x]!=ff){cal.push_back((Mod){nowid,x,fa[x]});top++;}
  66. return fa[x]=ff;
  67. }
  68. il void merge(int x,int y){
  69. x=find(x);y=find(y);if(x==y)return;
  70. cal.push_back((Mod){nowid,x,fa[x]});top++;
  71. fa[x]=y;
  72. }
  73. #define pd(i,j) (i<1||i>n||j<1||j>n||!vis[i][j])
  74. set<int>S;
  75. il void insert(int x,int y,int col){
  76. vis[x][y]=1;c[x][y]=col;nowid=p[x][y];
  77. S.clear();
  78. for(RG int k=0,xx,yy;k<4;k++){
  79. xx=x+dx[k];yy=y+dy[k];if(pd(xx,yy))continue;
  80. if(c[xx][yy]==c[x][y]){
  81. S.insert(find(p[xx][yy]));
  82. merge(p[x][y],p[xx][yy]);
  83. }
  84. }
  85. v[x][y]=1-S.size();col?b+=v[x][y]:w+=v[x][y];
  86. }
  87. il void undo(int x,int y){
  88. nowid=p[x][y];
  89. while(top&&cal[top-1].id==nowid)
  90. fa[cal[top-1].u]=cal[top-1].v,cal.pop_back(),top--;
  91. c[x][y]?b-=v[x][y]:w-=v[x][y];vis[x][y]=0;
  92. }
  93. void divide(int i,int l,int r){
  94. RG int sz=M[i].size();
  95. for(RG int k=0;k<sz;k++)
  96. insert(M[i][k].x,M[i][k].y,M[i][k].c);
  97. if(l==r)printf("%d %d\n",b,w);
  98. else{divide(ls,l,mid);divide(rs,mid+1,r);}
  99. for(RG int k=sz-1;~k;k--)
  100. undo(M[i][k].x,M[i][k].y);
  101. }
  102. int main()
  103. {
  104. n=read();
  105. for(RG int i=1;i<=n;i++)
  106. for(RG int j=1;j<=n;j++)
  107. {p[i][j]=++cnt;c[i][j]=read()^1;a[i][j].push_back(1);}
  108. m=read();
  109. for(RG int i=1,x,y;i<=m;i++){
  110. x=read();y=read();a[x][y].push_back(i);
  111. }
  112. for(RG int i=1;i<=n;i++)
  113. for(RG int j=1;j<=n;j++)
  114. a[i][j].push_back(m+1);
  115. for(RG int i=1;i<=n;i++)
  116. for(RG int j=1;j<=n;j++)
  117. for(RG int k=0,sz=a[i][j].size();k<sz-1;k++){
  118. c[i][j]^=1;now=(node){i,j,c[i][j]};
  119. if(a[i][j][k]!=a[i][j][k+1])
  120. modify(1,1,m,a[i][j][k],a[i][j][k+1]-1);
  121. }
  122. divide(1,1,m);
  123. return 0;
  124. }

[WC2005]双面棋盘的更多相关文章

  1. P4121 [WC2005]双面棋盘

    题目 P4121 [WC2005]双面棋盘 貌似是刘汝佳出的题目?? 做法 线段树维护并查集 线段树分治\(1\)~\(n\)行,我们要考虑维护的肯定是黑.白各自的联通块数量 考虑区间合并,其实就与中 ...

  2. 【题解】Luogu P4121 [WC2005]双面棋盘

    原题传送门 这道题肥肠毒瘤qwqwq,我被卡了qwqwq 这题的正解好像是线段树+并查集,但由于我人丑常数大被卡成了70 #include <bits/stdc++.h> #define ...

  3. [WC2005]双面棋盘(并查集+分治)

    题目描述 题解 唉,还是码力不行,写了一个多小时发现想错了又重构了一个多小时. 这道题意图很显然,动态维护联通块,有一个经典做法就是用LCT维护按照删除时间维护的最大生成树. 网上还有一种神奇的做法, ...

  4. [WC2005]双面棋盘(线段树+并查集)

    线段树+并查集维护连通性. 好像 \(700ms\) 的时限把我的常数超级大的做法卡掉了, 必须要开 \(O_2\) 才行. 对于线段树的每一个结点都开左边的并查集,右边的并查集,然后合并. \(Co ...

  5. 洛谷P4121 [WC2005]双面棋盘(线段树套并查集)

    传送门 先膜一下大佬->这里 据说这题正解是LCT,然而感觉还是线段树套并查集的更容易理解 我们对于行与行之间用线段树维护,每一行内用并查集暴力枚举 每一行内用并查集暴力枚举连通块这个应该容易理 ...

  6. 【BZOJ1453】[Wc]Dface双面棋盘 线段树+并查集

    [BZOJ1453][Wc]Dface双面棋盘 Description Input Output Sample Input Sample Output HINT 题解:话说看到题的第一反应其实是LCT ...

  7. bzoj 1453: [Wc]Dface双面棋盘

    1453: [Wc]Dface双面棋盘 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 617  Solved: 317[Submit][Status][ ...

  8. BZOJ1453: [WC2005]Dface双面棋盘

    离线LCT维护MST,和3082的方法一样.然而比较码农,适合颓废的时候写. PS:线段树分治要好写得多,LCT比较自娱自乐. #include<bits/stdc++.h> using ...

  9. 【BZOJ1453】[WC] Dface双面棋盘(LCT维护联通块个数)

    点此看题面 大致题意: 给你一个\(n*n\)的黑白棋盘,每次将一个格子翻转,分别求黑色连通块和白色连通块的个数. \(LCT\)动态维护图连通性 关于这一部分内容,可以参考这道例题:[BZOJ402 ...

随机推荐

  1. Java:二进制(原码、反码、补码)与位运算

    一.二进制(原码.反码.补码) 二进制的最高位是符号位(“0”代表正数,“1”代表负数): Java中没有无符号数: 计算机以整数的补码进行运算: 1.  原码:将一个整数转换成二进制表示 以 int ...

  2. 阿里otter使用问题汇总

    最近在使用otter做为和表从库.(100个分表太难查询了) user_00,user_01...user_99 => user_all 1.问题DDL语句不能执行(exception:setl ...

  3. VMWare虚拟机下 centos network is unreachable 问题的解决

    vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPROTO=static BROADCAST=192.168.1.255 HW ...

  4. android 学习六 构建用户界面和使用控件

    1.常用Android控件最终都会继承自View类 2.ViewGroup是一些布局类列表的基类,包括View和ViewGroup 3.构造界面的三种方法    a.完全使用代码(太灵活,而不好维护) ...

  5. (C#)工厂方法模式

    1.工厂方法模式 第一了一个用于创建对象的接口,让子类自己决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. *工厂方法模式即克服了简单工厂模式违反开放-封闭原则的缺点,又保留了封装对象创建过 ...

  6. Spring Cloud(七):配置中心(Git 版与动态刷新)【Finchley 版】

    Spring Cloud(七):配置中心(Git 版与动态刷新)[Finchley 版]  发表于 2018-04-19 |  更新于 2018-04-24 |  Spring Cloud Confi ...

  7. 【MFC】VS2017新建完MFC后,没有界面,只有代码

    问题描述:双击.rc文件后提示在另一个编辑器中打开 解决方法整合: 1----- 打开工程之前先把.rc文件改个名称,然后打开工程双击解决方案管理器的.rc文件, 会显示"载入失败" ...

  8. Python3 小工具-ARP欺骗

    在kali中使用 from scapy.all import * import optparse import os def send(pkt,interface): for p in pkt: se ...

  9. POJ 1815 Friendship(最大流最小割の字典序割点集)

    Description In modern society, each person has his own friends. Since all the people are very busy, ...

  10. 第一章 Windows编程基础(1~4课)

    第一课:从main到WinMain 第二课:窗口和消息 第三课:MFC编程 第四课:MFC应用程序框架 概括: Win32的两种编程框架:SDK方式.MFC方式 1. SDK方式:使用WinMain入 ...