线段树+并查集维护连通性。

好像 \(700ms\) 的时限把我的常数超级大的做法卡掉了, 必须要开 \(O_2\) 才行。

对于线段树的每一个结点都开左边的并查集,右边的并查集,然后合并。

\(Code\ Below:\)

  1. #include <bits/stdc++.h>
  2. #define lson (rt<<1)
  3. #define rson (rt<<1|1)
  4. using namespace std;
  5. const int maxn=200+10;
  6. int n,m,a[maxn][maxn],f[maxn<<2],tmp[maxn<<2],wsum[maxn<<2],bsum[maxn<<2],lfa[maxn<<2][maxn],rfa[maxn<<2][maxn];
  7. inline int read(){
  8. register int x=0,f=1;char ch=getchar();
  9. while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
  10. while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
  11. return (f==1)?x:-x;
  12. }
  13. int find(int x,int *f){
  14. return (x==f[x])?x:f[x]=find(f[x],f);
  15. }
  16. inline void pushup(int rt,int mid){
  17. wsum[rt]=wsum[lson]+wsum[rson];
  18. bsum[rt]=bsum[lson]+bsum[rson];
  19. for(int i=1;i<=n;i++){
  20. f[i]=lfa[lson][i];f[i+n]=rfa[lson][i];
  21. f[i+2*n]=lfa[rson][i]+2*n;f[i+3*n]=rfa[rson][i]+2*n;
  22. }
  23. for(int i=1;i<=n;i++)
  24. if(a[mid][i]==a[mid+1][i]){
  25. if(find(i+n,f)!=find(i+2*n,f)){
  26. f[find(i+n,f)]=f[find(i+2*n,f)];
  27. if(a[mid][i]==0) wsum[rt]--;
  28. else bsum[rt]--;
  29. }
  30. }
  31. for(int i=1;i<=n;i++) tmp[find(i,f)]=i;
  32. for(int i=3*n+1;i<=4*n;i++) tmp[find(i,f)]=i-2*n;
  33. for(int i=1;i<=n;i++){
  34. lfa[rt][i]=tmp[find(i,f)];
  35. rfa[rt][i]=tmp[find(i+3*n,f)];
  36. }
  37. }
  38. void build(int l,int r,int rt){
  39. if(l == r){
  40. for(int i=1;i<=n;i++) lfa[rt][i]=i;
  41. for(int i=1;i<=n;i++){
  42. if(a[l][i]==0) wsum[rt]++;
  43. else bsum[rt]++;
  44. if(a[l][i-1]==a[l][i]){
  45. lfa[rt][find(i-1,lfa[rt])]=i;
  46. if(a[l][i]==0) wsum[rt]--;
  47. else bsum[rt]--;
  48. }
  49. rfa[rt][i]=lfa[rt][i];
  50. }
  51. return ;
  52. }
  53. int mid=(l+r)>>1;
  54. build(l,mid,lson);
  55. build(mid+1,r,rson);
  56. pushup(rt,mid);
  57. }
  58. void modify(int x,int l,int r,int rt){
  59. if(l == r){
  60. wsum[rt]=bsum[rt]=0;
  61. for(int i=1;i<=n;i++) lfa[rt][i]=i;
  62. for(int i=1;i<=n;i++){
  63. if(a[l][i]==0) wsum[rt]++;
  64. else bsum[rt]++;
  65. if(a[l][i-1]==a[l][i]){
  66. lfa[rt][find(i-1,lfa[rt])]=i;
  67. if(a[l][i]==0) wsum[rt]--;
  68. else bsum[rt]--;
  69. }
  70. rfa[rt][i]=lfa[rt][i];
  71. }
  72. return ;
  73. }
  74. int mid=(l+r)>>1;
  75. if(x <= mid) modify(x,l,mid,lson);
  76. else modify(x,mid+1,r,rson);
  77. pushup(rt,mid);
  78. }
  79. int main()
  80. {
  81. n=read();
  82. for(int i=1;i<=n;i++) a[i][0]=-1;
  83. for(int i=1;i<=n;i++)
  84. for(int j=1;j<=n;j++) a[i][j]=read();
  85. build(1,n,1);
  86. m=read();
  87. int x,y;
  88. while(m--){
  89. x=read(),y=read();
  90. a[x][y]^=1;modify(x,1,n,1);
  91. printf("%d %d\n",bsum[1],wsum[1]);
  92. }
  93. return 0;
  94. }

[WC2005]双面棋盘(线段树+并查集)的更多相关文章

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

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

  2. 2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集)

    2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集) https://www.luogu.com.cn/problem/CF811E Ste ...

  3. codeforces 811E Vladik and Entertaining Flags(线段树+并查集)

    codeforces 811E Vladik and Entertaining Flags 题面 \(n*m(1<=n<=10, 1<=m<=1e5)\)的棋盘,每个格子有一个 ...

  4. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

  5. 【XSY2707】snow 线段树 并查集

    题目描述 有\(n\)个人和一条长度为\(t\)的线段,每个人还有一个工作范围(是一个区间).最开始整条线段都是白的.定义每个人的工作长度是这个人的工作范围中白色部分的长度(会随着线段改变而改变).每 ...

  6. bzoj 2054: 疯狂的馒头(线段树||并查集)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2054 线段树写法: 点的颜色只取决于最后一次染的颜色,所以我们可以倒着维护,如果当前区间之前 ...

  7. 【CF687D】Dividing Kingdom II 线段树+并查集

    [CF687D]Dividing Kingdom II 题意:给你一张n个点m条边的无向图,边有边权$w_i$.有q个询问,每次给出l r,问你:如果只保留编号在[l,r]中的边,你需要将所有点分成两 ...

  8. 【Codeforces811E】Vladik and Entertaining Flags [线段树][并查集]

    Vladik and Entertaining Flags Time Limit: 20 Sec  Memory Limit: 512 MB Description n * m的矩形,每个格子上有一个 ...

  9. 【BZOJ 4662】 4662: Snow (线段树+并查集)

    4662: Snow Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 136  Solved: 47 Description 2333年的某一天,临冬突 ...

随机推荐

  1. 微信小程序开发工具常用快捷键

    格式调整 Ctrl+S:保存文件 Ctrl+[, Ctrl+]:代码行缩进 Ctrl+Shift+[, Ctrl+Shift+]:折叠打开代码块 Ctrl+C Ctrl+V:复制粘贴,如果没有选中任何 ...

  2. 扩展方法(深入理解c#)

    1. 静态类到扩展方法: 许多方法可能都适合转为扩展方法,只要具有以下特征: 1)你想为一个类型添加一些成员: 2)你不需要为类型的实例添加更多的数据: 3)你不能改变类型本身,因为是别人的代码 2. ...

  3. linux 安装 ORACLE JDK 8

    1.卸载默认的OPENJDK 查看 open jdk 的安装 rpm -qa | grep java 卸载 openjdk rpm -e --nodeps java-1.7.0-openjdk-1.7 ...

  4. jitter

    release jitter of tasks there is a distinction between the real activation request and the actual ac ...

  5. rm与管道使用

    一 问题初始:用通常意义的管道使用这样可以:(1)ls -l | sed -n '/~$/p' 我用显示出系统自己建立的备份文件这时,我想删除这些文件,我仍然使用了管道,并执行了以下命令(2)ls - ...

  6. IntelliJ IDEA 2017版 spring-boot2.0.2 搭建 JPA springboot DataSource JPA环境搭建,JPA注解@ManyToOne使用详情;JPA外键设置

    一.数据库原型 数据库模型如图所示,而现在需要根据数据库模型,建立对应的实体类,这在项目重构老数据库,采用新的框架重构上应该是比较常见的. 数据库脚本如下: CREATE TABLE `bomsub` ...

  7. eclipse 创建servlet 出现继承 HttpServlet 报红线

    eclipse创建servlet出现红线: 解决方案1,鼠标右键项目 -> 鼠标右击项目——>Build Path——> 点击comfigure Build Path进入-----& ...

  8. python 基础_ 数组的 增删改查3

    数组是运用在多个数据存在一个变量中的,而在调用的时候可以调用所需要的数组. 创建数组 a = ['a','b','c','d','f'] #创建一个数组a其中有5个元素分别是abcdf 1.查询.所谓 ...

  9. VIP之FrameBuffer

     2.VIP Frame Buffer 1.原来我是一直存在一个疑惑,demo上说VIP Frame Buffer输出是固定的60fps,但是在NiosII的程序中我没有找到设置输出为60fps的设置 ...

  10. C++二级指针第一种内存模型(指针数组)

    二级指针第一种内存模型(指针数组) 指针的输入特性:在主调函数里面分配内存,在被调用函数里面使用指针的输出特性:在被调用函数里面分配内存,主要是把运算结果甩出来 指针数组 在C语言和C++语言中,数组 ...