[Wc]Dface双面棋盘
2018-01-04 21:43
337 查看
Description
![](http://www.lydsy.com/JudgeOnline/images/1453_1.jpg)
Input
![](http://www.lydsy.com/JudgeOnline/images/1453_2.jpg)
Output
![](http://www.lydsy.com/JudgeOnline/images/1453_3.jpg)
Sample Input
![](http://www.lydsy.com/JudgeOnline/images/1453_4.jpg)
Sample Output
![](http://www.lydsy.com/JudgeOnline/images/1453_5.jpg)
HINT
![](http://www.lydsy.com/JudgeOnline/images/1453_6.jpg)
线段树+并查集,暴力记录和更新一些信息,详情见代码注解。
![](http://www.lydsy.com/JudgeOnline/images/1453_1.jpg)
Input
![](http://www.lydsy.com/JudgeOnline/images/1453_2.jpg)
Output
![](http://www.lydsy.com/JudgeOnline/images/1453_3.jpg)
Sample Input
![](http://www.lydsy.com/JudgeOnline/images/1453_4.jpg)
Sample Output
![](http://www.lydsy.com/JudgeOnline/images/1453_5.jpg)
HINT
![](http://www.lydsy.com/JudgeOnline/images/1453_6.jpg)
线段树+并查集,暴力记录和更新一些信息,详情见代码注解。
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define inf 0x7f7f7f7f using namespace std; typedef long long ll; typedef unsigned int ui; typedef unsigned long long ull; inline int read(){ int x=0,f=1;char ch=getchar(); for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1; for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0'; return x*f; } inline void print(int x){ if (x>=10) print(x/10); putchar(x%10+'0'); } const int N=2e2; int map[N+10][N+10]; int ID[N*4+10],fa[N*4+10]; int n,m; int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} struct Segment{ #define ls (p<<1) #define rs (p<<1|1) struct AC{//线段树记录列数,struct内存储一个列区间的信息 int lcnt[N+10],rcnt[N+10]; //记录最左列和最右列每行的联通块个数,相当于编号 int W,B,T; //记录白块(W),黑块(B)个数,T为lcnt +rcnt int l,r; void clear(){ l=r=W=B=T=0; memset(lcnt,0,sizeof(lcnt)); memset(rcnt,0,sizeof(rcnt)); } void init(int x){//单点暴力 B=W=0; for (i b40b nt i=1;i<=n;i++){ if (i==1||map[i][x]!=map[i-1][x]) map[i][x]?B++:W++; lcnt[i]=rcnt[i]=B+W; } T=B+W; } }tree[N*4+10]; friend AC operator +(const AC &x,const AC &y){ AC z; z.clear(); z.l=x.l,z.r=y.r; z.B=x.B+y.B; z.W=x.W+y.W; for (int i=1;i<=x.T+y.T;i++) fa[i]=i,ID[i]=0; //T的用处(优化) for (int i=1,p1,p2;i<=n;i++){//把y的信息加上x.T,使它们为一个图 if (map[i][x.r]!=map[i][y.l]) continue; if ((p1=find(x.rcnt[i]))!=(p2=find(y.lcnt[i]+x.T))){ fa[p2]=p1; //记得连向小的标号…… map[i][x.r]?z.B--:z.W--; } } int Rank=0; for (int i=1;i<=n;i++){//离散化 int p1=find(x.lcnt[i]),p2=find(y.rcnt[i]+x.T); if (!ID[p1]) ID[p1]=++Rank; if (!ID[p2]) ID[p2]=++Rank; z.lcnt[i]=ID[p1]; z.rcnt[i]=ID[p2]; } z.T=Rank; return z; } void build(int p,int l,int r){ tree[p].l=l,tree[p].r=r; if (l==r){ tree[p].init(l); return; } int mid=(l+r)>>1; build(ls,l,mid),build(rs,mid+1,r); tree[p]=tree[ls]+tree[rs]; } void change(int p,int l,int r,int x){ if (l==r){ tree[p].init(l); return; } int mid=(l+r)>>1; if (x<=mid) change(ls,l,mid,x); if (x>mid) change(rs,mid+1,r,x); tree[p]=tree[ls]+tree[rs]; } void work(){ int x=read(),y=read(); map[x][y]^=1; change(1,1,n,y); printf("%d %d\n",tree[1].B,tree[1].W); } }T; int main(){ n=read(); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) map[i][j]=read(); T.build(1,1,n); m=read(); for (int i=1;i<=m;i++) T.work(); return 0; }
相关文章推荐
- BZOJ1453: [Wc]Dface双面棋盘
- BZOJ1453: [WC2005]Dface双面棋盘
- WC 2005 dface 双面棋盘
- [BZOJ1453][Wc]Dface双面棋盘(lct)
- BZOJ1453 : [Wc]Dface双面棋盘
- 1453: [Wc]Dface双面棋盘 (线段树+并茶几)
- BZOJ 1453 Wc2005 Dface双面棋盘 Link-Cut-Tree
- 【BZOJ1453】[Wc]Dface双面棋盘 线段树+并查集
- BZOJ1453: [Wc]Dface双面棋盘
- [CDQ分治 并查集] BZOJ 1453 [Wc]Dface双面棋盘
- 【BZOJ】【P1453】【WC2005】【Dface双面棋盘】【题解】【线段树+并查集】
- BZOJ 1453 [WC] 双面棋盘 并查集+线段树暴搞
- BZOJ1453 WCDface 双面棋盘
- [UOJ 287][WC 2017] 棋盘
- bzoj 1453 双面棋盘 LCT 并查集
- 棋盘问题 DFS+回溯
- 【BZOJ4813】 [Cqoi2017]小Q的棋盘
- hdu 2067 小兔的棋盘 (DP)
- 棋盘问题
- Hdu 1281 棋盘游戏