题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1453

题意:一个 n*n 的矩阵,每个位置有黑/白两种颜色,有 m 次操作,每次可以翻转其中一个位置的格子颜色,问每次操作后黑色和白色连通块的个数。

题解:考虑若没有翻转颜色的操作时,可以用并查集来找出两种连通块的个数,加上修改的操作,可以用线段树维护并查集的信息。对每列建线段树,合并时将边界合并,修改从叶子到根进行合并,详见代码~

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset((a),(b),sizeof(a))
#define mp(a,b) make_pair(a,b)
#define pi acos(-1)
#define pii pair<int,int>
#define pb push_back
const int INF = 0x3f3f3f3f;
const double eps = 1e-;
const int MAXN = 3e5 + ;
const int MAXM = 1e7 + ;
const ll mod = 1e9 + ; int n, m;
int s[][], fa[ * ]; int id(int x,int y) {
return x * n + y;
} int findd(int x) {
return x == fa[x] ? x : fa[x] = findd(fa[x]);
} struct node {
int l[],r[],ans[];
}st[<<]; node mergee(node &a,node &b,int mid) {
node c;
for(int i = ; i <= n; i++) {
c.l[i] = a.l[i], c.r[i] = b.r[i];
fa[a.l[i]] = a.l[i], fa[a.r[i]] = a.r[i];
fa[b.l[i]] = b.l[i], fa[b.r[i]] = b.r[i];
}
for(int i = ; i < ; i++) c.ans[i] = a.ans[i] + b.ans[i];
for(int i = ; i <= n; i++) {
if(s[i][mid] == s[i][mid + ]) {
int x = findd(a.r[i]), y = findd(b.l[i]);
if(x == y) continue;
c.ans[s[i][mid]]--, fa[x] = y;
}
}
for(int i = ; i <= n; i++) {
c.l[i] = findd(c.l[i]);
c.r[i] = findd(c.r[i]);
}
return c;
} void build(int rt,int l,int r) {
if(l == r) {
st[rt].ans[] = st[rt].ans[] = ;
for(int i = ; i <= n; i++) {
st[rt].l[i] = st[rt].r[i] = fa[id(i,l)] = id(i,l);
st[rt].ans[s[i][l]]++;
}
for(int i = ; i <= n; i++) {
if(s[i][l] == s[i - ][l]) {
st[rt].l[i] = st[rt].r[i] = fa[id(i,l)] = fa[id(i - ,l)];
st[rt].ans[s[i][l]]--;
}
}
return ;
}
int mid = (l + r) >> ;
build(rt<<,l,mid);
build(rt<<|,mid + ,r);
st[rt] = mergee(st[rt<<],st[rt<<|],mid);
} void update(int rt,int l,int r,int pos) {
if(l == r) {
st[rt].ans[] = st[rt].ans[] = ;
for(int i = ; i <= n; i++) {
st[rt].l[i] = st[rt].r[i] = fa[id(i,l)] = id(i,l);
st[rt].ans[s[i][l]]++;
}
for(int i = ; i <= n; i++) {
if(s[i][l] == s[i - ][l]) {
st[rt].l[i] = st[rt].r[i] = fa[id(i,l)] = fa[id(i - ,l)];
st[rt].ans[s[i][l]]--;
}
}
return ;
}
int mid = (l + r) >> ;
if(pos <= mid) update(rt<<,l,mid,pos);
else update(rt<<|,mid + ,r,pos);
st[rt] = mergee(st[rt<<],st[rt<<|],mid);
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
scanf("%d",&n);
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
scanf("%d",&s[i][j]);
build(,,n);
scanf("%d",&m);
while(m--) {
int x,y;
scanf("%d%d",&x,&y);
s[x][y] ^= ;
update(,,n,y);
printf("%d %d\n",st[].ans[],st[].ans[]);
}
return ;
}

BZOJ 1453 (线段树+并查集)的更多相关文章

  1. BZOJ 3211 线段树+并查集

    思路: 我们很容易发现 一个数开根号 开几(很小)次 就到了1 1 再怎么开 都是1 由于这个性质 我们就可以用并查集 了 //By SiriusRen #include <cmath> ...

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

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

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

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

  4. [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+并查集+启发式合并)

    [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+启发式合并) 题面 给出一个n个节点m条边的森林,每个节点都有一个权值.有两种操作: Q x y k查询点x到点y路径上所有的权值中 ...

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

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

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

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

  7. BZOJ 3319 黑白树 并查集+线段树

    这这这这这这什么毒瘤题!!!!!!!!!!!!!!!!!!!!!!!!!!!! 卡LCT(优秀的LCT由于是均摊本身就带着2,3的常数在,而且这道题对于LCT标记十分难维护,又得乘上4,5然后就炸了) ...

  8. BZOJ 2733 [HNOI2012]永无乡 ——线段树 并查集

    用并查集维护联通块. 用线段树的合并来合并联通块. 自己YY了一个写法. #include <map> #include <cmath> #include <queue& ...

  9. poj 2528 Mayor's posters 线段树 || 并查集 离线处理

    题目链接 题意 用不同颜色的线段覆盖数轴,问最终数轴上有多少种颜色? 注:只有最上面的线段能够被看到:即,如果有一条线段被其他的线段给完全覆盖住,则这个颜色是看不到的. 法一:线段树 按题意按顺序模拟 ...

随机推荐

  1. cent7配置阿里yum源

    阿里云Linux安装镜像源地址:http://mirrors.aliyun.com/CentOS系统更换软件安装源第一步:备份你的原镜像文件,以免出错后可以恢复.mv /etc/yum.repos.d ...

  2. 《C专家编程》读书笔记之第8~11章

    八.为什么程序员无法分清万圣节和圣诞节 1. 整形提升是指char,short int和位段类型(无论signed或unsigned)以及枚举类型将被提升为int或unsigned int(如果int ...

  3. Oracle学习记录(一)

    一.Oracle历史 于1977年拉里埃里森和他三个朋友成立了软件研发公司,并在之后给中央情报局开发了命名为Oracle而出名,并在之后将公司名改为Oracle.1989年以甲骨文命名进入中国. Or ...

  4. springboot通过slf4j配置日志

    原因:SpringBoot默认使用slf4j日志,引入其他框架的时候,只需要把这个框架依赖的日志框架排除掉: 而我今天想引入log4j的时候,pom文件一直报错,显示找不到log4j的jar包,应当是 ...

  5. PHP后台开发小经验

    js页面传参数 js的参数传输是关键,尤其是当一个页面的数据需要分步骤上传时. 同样的删除功能,不会操作批量删除时可以尝试单个删除,功能差不多,实现功能的方法也千千万,先做成它是第一位. 主页面很多条 ...

  6. java方法可变参数研究

    1 问题引出 (1)缘由 最近在研究如何在项目中引入Redis缓存,于是遇到可变参数这个疑惑点,之前没有好好研究过,为了避免项目后期出现问题. (2)项目相关技术 SpringBoot Redis K ...

  7. Sql Server 分区演练

    USE [master] GO if exists (select * from sys.databases where name = 'Test_1') drop database Test_1 G ...

  8. PCQQ - 发送自定义的XML卡片消息

    效果: 原理: qq分享产生的xml卡片消息存储在qq内存中,可以在qq运行内存中搜索找到其xml源码,记录源码相应的内存地址,通过内存地址修改掉内存数据,再次转发这条分享的消息就会发现内容的变化. ...

  9. C# 填充无效,无法被移除

    1.本文采用微软的 RijndaelManaged 命名空间: System.Security.Cryptography Assemblies: mscorlib.dll, netstandard.d ...

  10. BootStrap【四、插件】

    BootStrap插件基于: 1.BootStrap.js 2.BootStrap.js基于JQuery data属性 1.通过data属性控制页面交互 2.$(document).off('.dat ...