[WC2005]双面棋盘(线段树+并查集)
线段树+并查集维护连通性。
好像 \(700ms\) 的时限把我的常数超级大的做法卡掉了, 必须要开 \(O_2\) 才行。
对于线段树的每一个结点都开左边的并查集,右边的并查集,然后合并。
\(Code\ Below:\)
#include <bits/stdc++.h>
#define lson (rt<<1)
#define rson (rt<<1|1)
using namespace std;
const int maxn=200+10;
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];
inline int read(){
register int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return (f==1)?x:-x;
}
int find(int x,int *f){
return (x==f[x])?x:f[x]=find(f[x],f);
}
inline void pushup(int rt,int mid){
wsum[rt]=wsum[lson]+wsum[rson];
bsum[rt]=bsum[lson]+bsum[rson];
for(int i=1;i<=n;i++){
f[i]=lfa[lson][i];f[i+n]=rfa[lson][i];
f[i+2*n]=lfa[rson][i]+2*n;f[i+3*n]=rfa[rson][i]+2*n;
}
for(int i=1;i<=n;i++)
if(a[mid][i]==a[mid+1][i]){
if(find(i+n,f)!=find(i+2*n,f)){
f[find(i+n,f)]=f[find(i+2*n,f)];
if(a[mid][i]==0) wsum[rt]--;
else bsum[rt]--;
}
}
for(int i=1;i<=n;i++) tmp[find(i,f)]=i;
for(int i=3*n+1;i<=4*n;i++) tmp[find(i,f)]=i-2*n;
for(int i=1;i<=n;i++){
lfa[rt][i]=tmp[find(i,f)];
rfa[rt][i]=tmp[find(i+3*n,f)];
}
}
void build(int l,int r,int rt){
if(l == r){
for(int i=1;i<=n;i++) lfa[rt][i]=i;
for(int i=1;i<=n;i++){
if(a[l][i]==0) wsum[rt]++;
else bsum[rt]++;
if(a[l][i-1]==a[l][i]){
lfa[rt][find(i-1,lfa[rt])]=i;
if(a[l][i]==0) wsum[rt]--;
else bsum[rt]--;
}
rfa[rt][i]=lfa[rt][i];
}
return ;
}
int mid=(l+r)>>1;
build(l,mid,lson);
build(mid+1,r,rson);
pushup(rt,mid);
}
void modify(int x,int l,int r,int rt){
if(l == r){
wsum[rt]=bsum[rt]=0;
for(int i=1;i<=n;i++) lfa[rt][i]=i;
for(int i=1;i<=n;i++){
if(a[l][i]==0) wsum[rt]++;
else bsum[rt]++;
if(a[l][i-1]==a[l][i]){
lfa[rt][find(i-1,lfa[rt])]=i;
if(a[l][i]==0) wsum[rt]--;
else bsum[rt]--;
}
rfa[rt][i]=lfa[rt][i];
}
return ;
}
int mid=(l+r)>>1;
if(x <= mid) modify(x,l,mid,lson);
else modify(x,mid+1,r,rson);
pushup(rt,mid);
}
int main()
{
n=read();
for(int i=1;i<=n;i++) a[i][0]=-1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) a[i][j]=read();
build(1,n,1);
m=read();
int x,y;
while(m--){
x=read(),y=read();
a[x][y]^=1;modify(x,1,n,1);
printf("%d %d\n",bsum[1],wsum[1]);
}
return 0;
}
[WC2005]双面棋盘(线段树+并查集)的更多相关文章
- 【BZOJ1453】[Wc]Dface双面棋盘 线段树+并查集
[BZOJ1453][Wc]Dface双面棋盘 Description Input Output Sample Input Sample Output HINT 题解:话说看到题的第一反应其实是LCT ...
- 2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集)
2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集) https://www.luogu.com.cn/problem/CF811E Ste ...
- codeforces 811E Vladik and Entertaining Flags(线段树+并查集)
codeforces 811E Vladik and Entertaining Flags 题面 \(n*m(1<=n<=10, 1<=m<=1e5)\)的棋盘,每个格子有一个 ...
- 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1878 Solved: 846[Submit][Status ...
- 【XSY2707】snow 线段树 并查集
题目描述 有\(n\)个人和一条长度为\(t\)的线段,每个人还有一个工作范围(是一个区间).最开始整条线段都是白的.定义每个人的工作长度是这个人的工作范围中白色部分的长度(会随着线段改变而改变).每 ...
- bzoj 2054: 疯狂的馒头(线段树||并查集)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2054 线段树写法: 点的颜色只取决于最后一次染的颜色,所以我们可以倒着维护,如果当前区间之前 ...
- 【CF687D】Dividing Kingdom II 线段树+并查集
[CF687D]Dividing Kingdom II 题意:给你一张n个点m条边的无向图,边有边权$w_i$.有q个询问,每次给出l r,问你:如果只保留编号在[l,r]中的边,你需要将所有点分成两 ...
- 【Codeforces811E】Vladik and Entertaining Flags [线段树][并查集]
Vladik and Entertaining Flags Time Limit: 20 Sec Memory Limit: 512 MB Description n * m的矩形,每个格子上有一个 ...
- 【BZOJ 4662】 4662: Snow (线段树+并查集)
4662: Snow Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 136 Solved: 47 Description 2333年的某一天,临冬突 ...
随机推荐
- 【转】你知道C#中的Lambda表达式的演化过程吗?
[转]你知道C#中的Lambda表达式的演化过程吗? 那得从很久很久以前说起了,记得那个时候... 懵懂的记得从前有个叫委托的东西是那么的高深难懂. 委托的使用 例一: 什么是委托? 个人理解:用来传 ...
- 【Go】 Go 语言环境安装
安装环境/工具 1.Linux(CentOS 7.4版) 2.go1.11.2.linux-amd64.tar Go 语言环境安装 1.下载安装包 安装包下载地址为:https://golang.or ...
- 子数整数(P1151&NOIP水题测试(2017082301))
题目链接:子数整数 水题,不解释,自己看代码: #include<bits/stdc++.h> using namespace std; int main(){ int k; scanf( ...
- 2018.12.17 bzoj1406 : [AHOI2007]密码箱(简单数论)
传送门 简单数论暴力题. 题目简述:要求求出所有满足x2≡1mod  nx^2\equiv1 \mod nx2≡1modn且0≤x<n0\ ...
- 2018.11.09 bzoj2165: 大楼(倍增+floyd)
传送门 先倍增出iii使得2i2^i2i时间时刚好有每个点能够到mmm层及以上. 然后就可以用floyd+floyd+floyd+倍增求出刚好不超过mmm层的时间,最后再补一层就行了. 代码: #pr ...
- 安装kafka 集群 步骤
1.下载 http://mirror.bit.edu.cn/apache/kafka/2.1.0/kafka_2.11-2.1.0.tgz 2.解压 tar -zxvf kafka_2.11-2.1 ...
- App测试基本流程详解(汇总整理)
前言 看过许多大神对APP测试的理解,博主总结了一下我们平时测试APP应该注意的一些测试点并结合大神的理解,总结出这篇文章. 一.测试周期 测试周期一般为两周,根据项目情况以及版本质量可适当缩短或延长 ...
- openstack的网络、子网、端口的关系
network network 是一个隔离的二层广播域.Neutron 支持多种类型的 network,包括 local, flat, VLAN, VxLAN 和 GRE. locallocal 网络 ...
- Mysql中Left Join Right Join Inner Join where条件的比较
建立一对多的表 company 和 employee company表 id name address 1baidu北京 2huawei深圳 3jingdong北京 4tengxu ...
- [待完善]mycat分布式架构部署
mycat介绍:http://mycat.org.cn/ mycat分布式架构部署