BZOJ 1453 (线段树+并查集)
题目链接: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 (线段树+并查集)的更多相关文章
- BZOJ 3211 线段树+并查集
思路: 我们很容易发现 一个数开根号 开几(很小)次 就到了1 1 再怎么开 都是1 由于这个性质 我们就可以用并查集 了 //By SiriusRen #include <cmath> ...
- [WC2005]双面棋盘(线段树+并查集)
线段树+并查集维护连通性. 好像 \(700ms\) 的时限把我的常数超级大的做法卡掉了, 必须要开 \(O_2\) 才行. 对于线段树的每一个结点都开左边的并查集,右边的并查集,然后合并. \(Co ...
- 2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集)
2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集) https://www.luogu.com.cn/problem/CF811E Ste ...
- [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+并查集+启发式合并)
[BZOJ 3123] [SDOI 2013]森林(可持久化线段树+启发式合并) 题面 给出一个n个节点m条边的森林,每个节点都有一个权值.有两种操作: Q x y k查询点x到点y路径上所有的权值中 ...
- bzoj 2054: 疯狂的馒头(线段树||并查集)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2054 线段树写法: 点的颜色只取决于最后一次染的颜色,所以我们可以倒着维护,如果当前区间之前 ...
- 【BZOJ 4662】 4662: Snow (线段树+并查集)
4662: Snow Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 136 Solved: 47 Description 2333年的某一天,临冬突 ...
- BZOJ 3319 黑白树 并查集+线段树
这这这这这这什么毒瘤题!!!!!!!!!!!!!!!!!!!!!!!!!!!! 卡LCT(优秀的LCT由于是均摊本身就带着2,3的常数在,而且这道题对于LCT标记十分难维护,又得乘上4,5然后就炸了) ...
- BZOJ 2733 [HNOI2012]永无乡 ——线段树 并查集
用并查集维护联通块. 用线段树的合并来合并联通块. 自己YY了一个写法. #include <map> #include <cmath> #include <queue& ...
- poj 2528 Mayor's posters 线段树 || 并查集 离线处理
题目链接 题意 用不同颜色的线段覆盖数轴,问最终数轴上有多少种颜色? 注:只有最上面的线段能够被看到:即,如果有一条线段被其他的线段给完全覆盖住,则这个颜色是看不到的. 法一:线段树 按题意按顺序模拟 ...
随机推荐
- [LuoguP2159][SHOI2009]舞会_动态规划_高精度_排列组合
舞会 题目链接:https://www.luogu.org/problem/P2159 数据范围:略. 题解: 不会.... 看了题解觉得自己好傻逼啊
- 原生js实现图片的3d效果
<!doctype html><html lang="en"><head><meta charset="UTF-8"& ...
- No package 'eventlog' found
syslog-ng のインスト�ル手� ●ダウンロ�ドサイト http://www.balabit.com/downloads/files/syslog-ng/sources/stable/src/ ...
- Git初始化配置以及配置github
1,配置用户名和邮箱(这里是我github中配置的用户名和邮箱),执行下面命令后,在C:\Users\yaosq盘下会出现一个全局文件.gitconfig. git config --global u ...
- 【AtCoder】ARC070
ARC070 C - Go Home 题目大意:一只袋鼠第i秒可以向左或向右跳i步或者不跳,问从0跳到x的最小时间 就是1,2,3,4...k总和超过x的最小的k,因为如果超过了x的那部分需要减掉的那 ...
- 网站页面顶部出现空白行字符的原因以及完美解决办法
转自个人博客:https://www.hurbai.com 有时候网页头部会出现一个空白行,查看源码发现body开头初有一个非法字符 // 如果是Windows系统,修改为:$WIN = 1; $W ...
- Synchronized&Lock&AQS详解
加锁目的:由于线程执行的过程是不可控的,所以需要采用同步机制来协同对对象可变状态的访问. 加锁方式:java锁分为两种--显示锁和隐示锁,本质区别在于显示锁需要的是程序员自己手动的进行加锁与解锁如Re ...
- kubernetes 实现redis-statefulset集群
Kubernetes 通过statefulset部署redis cluster集群 部署redis集群方式的选择 Statefulset Service&depolyment 对于redis, ...
- SparkSQL读取HBase数据
这里的SparkSQL是指整合了Hive的spark-sql cli(关于SparkSQL和Hive的整合,见文章后面的参考阅读). 本质上就是通过Hive访问HBase表,具体就是通过hive-hb ...
- 使用python+selenium获得b站今日播放的动漫
from selenium import webdriver browser=webdriver.Chrome() browser.get('https://www.bilibili.com/anim ...