【WC2005】【BZOJ1453】Dface双面棋盘
来源:互联网 发布:javascript弹出框原理 编辑:程序博客网 时间:2024/04/30 21:34
Description
Input
Output
Sample Input
Sample Output
HINT
Source
动态图问题(和徐寅展讲的不一样,这个事可以离线的)
LCT维护删除时间的最大生成树,和4025一个姿势
注意Cut时候判断一下是不是要更改答案
我的LCT因为姿势不优美一开始MLE了
蟹蟹雅礼中学的Dashgua君帮我改了改姿势QwQ
AC code↓
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#define MAXN 40100#define SIZE 210#define GET (ch>='0'&&ch<='9')using namespace std;int n,m,top,Top;int ans[3];int sta[MAXN*3],T;int a[SIZE][SIZE];int dx[5]={0,0,0,1,-1},dy[5]={0,1,-1,0,0};void in(int &x){ char ch=getchar();x=0; while (!GET) ch=getchar(); while (GET) x=x*10+ch-'0',ch=getchar();}const int poolsize = 200020;int poolv[poolsize], next[poolsize], pind;struct edge{ int u,v; struct queue { int head, tail; int front() { return poolv[head]; } void push(int v) { poolv[++pind] = v, next[tail] = pind, tail = pind; if(head == 0) head = pind; } void pop() { head = next[head]; } } w;}e[MAXN*3];struct splay{ int ch[2],fa,st; bool rev;}tree[MAXN*3];int num(int x,int y) {return x*n-n+y;}void insert(int u,int v) { e[++top].u=u;e[top].v=v;tree[top].st=top;}bool is_root(int x) {return tree[tree[x].fa].ch[0]!=x&&tree[tree[x].fa].ch[1]!=x;}void push_down(int x){ if (tree[x].rev) { tree[tree[x].ch[0]].rev^=1;tree[tree[x].ch[1]].rev^=1; swap(tree[x].ch[0],tree[x].ch[1]); } tree[x].rev=0;}void push_up(int x){ int l=tree[x].ch[0],r=tree[x].ch[1];tree[x].st=x; if (l&&e[tree[l].st].w.front()<e[tree[x].st].w.front()) tree[x].st=tree[l].st; if (r&&e[tree[r].st].w.front()<e[tree[x].st].w.front()) tree[x].st=tree[r].st;}void rot(int x){ int y=tree[x].fa,z=tree[y].fa,l,r; l=(tree[y].ch[1]==x);r=l^1; if (!is_root(y)) tree[z].ch[tree[z].ch[1]==y]=x; tree[x].fa=z;tree[y].fa=x;tree[tree[x].ch[r]].fa=y; tree[y].ch[l]=tree[x].ch[r];tree[x].ch[r]=y; push_up(y);push_up(x);}void Splay(int x){ sta[++T]=x; for (int i=x;!is_root(i);i=tree[i].fa) sta[++T]=tree[i].fa; while (T) push_down(sta[T--]); while (!is_root(x)) { int y=tree[x].fa,z=tree[y].fa; if (!is_root(y)) { if ((tree[z].ch[0]==y)^(tree[y].ch[0]==x)) rot(x); else rot(y); } rot(x); }}void access(int x){ for (int i=0;x;i=x,x=tree[x].fa) Splay(x),tree[x].ch[1]=i,push_up(x);}void make_root(int x){ access(x);Splay(x);tree[x].rev^=1;}void link(int x,int y){ make_root(x);tree[x].fa=y;}/*void cut(int x,int y){ make_root(x);access(y);Splay(y);tree[y].ch[0]=tree[x].fa=0;push_up(y);}*/bool cut(int x,int y){ make_root(x);access(y);Splay(y); if (tree[y].ch[0]!=x||tree[x].ch[1]!=0) return 0; tree[y].ch[0]=tree[x].fa=0;push_up(y);return 1;}void split(int x,int y){ make_root(x);access(y);Splay(y);}int find(int x){ access(x);Splay(x); for (;tree[x].ch[0];x=tree[x].ch[0]); return x;}void add(int x,int col){ int u=e[x].u,v=e[x].v; if (find(u)!=find(v)) link(u,x),link(v,x),ans[col]--; else { split(u,v);int y=tree[v].st; if (e[y].w.front()<e[x].w.front()) cut(e[y].u,y),cut(e[y].v,y),link(e[x].u,x),link(e[x].v,x); }}void del(int x,int col){ int u=e[x].u,v=e[x].v; if (cut(x,u)&&cut(x,v)) ans[col]++; e[x].w.pop();}struct Query {short x,y;}q[10010];bool in_size(int x,int y) {return !(x<=0||y<=0||x>n||y>n);}int main(){ in(n);int x,y; for (int i=1;i<=n*n;i++) insert(0,0),e[top].w.push(10010); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) in(a[i][j]),tree[num(i,j)].st=Top; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) insert(num(i,j),num(i,j+1)); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) insert(num(i,j),num(i+1,j)); in(m); for (int i=1;i<=m;i++) { in(x);in(y);q[i]=(Query){(short)x,(short)y}; for (int j=1;j<=4;j++) { int tx=x+dx[j],ty=y+dy[j]; if (!in_size(tx,ty)) continue; if (a[x][y]==a[tx][ty]) e[min(num(x,y),num(tx,ty))+(((j-1)>>1)+1)*n*n].w.push(i); } a[x][y]^=1; } for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { int tx=i,ty=j+1; if (in_size(tx,ty)&&a[i][j]==a[tx][ty]) e[num(i,j)+n*n].w.push(m+1); tx=i+1;ty=j; if (in_size(tx,ty)&&a[i][j]==a[tx][ty]) e[num(i,j)+(n*n<<1)].w.push(m+1); } for (int i=m;i;i--) a[q[i].x][q[i].y]^=1; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) ans[a[i][j]]++; int cnt=0; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { int tx=i,ty=j+1; if (in_size(tx,ty)&&a[i][j]==a[tx][ty]) add(num(i,j)+n*n,a[i][j]),cnt++; tx=i+1;ty=j; if (in_size(tx,ty)&&a[i][j]==a[tx][ty]) add(num(i,j)+(n*n<<1),a[i][j]),cnt++; } for (int i=1;i<=m;i++) { x=q[i].x;y=q[i].y; for (int j=1;j<=4;j++) { int tx=x+dx[j],ty=y+dy[j]; if (in_size(tx,ty)&&a[x][y]==a[tx][ty]) del(min(num(x,y),num(tx,ty))+(((j-1)>>1)+1)*n*n,a[x][y]); } ans[a[x][y]]--;a[x][y]^=1;ans[a[x][y]]++; for (int j=1;j<=4;j++) { int tx=x+dx[j],ty=y+dy[j]; if (in_size(tx,ty)&&a[x][y]==a[tx][ty]) add(min(num(x,y),num(tx,ty))+(((j-1)>>1)+1)*n*n,a[x][y]); } printf("%d %d\n",ans[1],ans[0]); }}
MLE code↓
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#define MAXN 40100#define SIZE 210#define GET (ch>='0'&&ch<='9')using namespace std;int n,m,top,Top;int ans[3];int sta[MAXN*3],T;int a[SIZE][SIZE];int dx[5]={0,0,0,1,-1},dy[5]={0,1,-1,0,0};void in(int &x){ char ch=getchar();x=0; while (!GET) ch=getchar(); while (GET) x=x*10+ch-'0',ch=getchar();}struct edge{ int u,v; queue<short> w;}e[MAXN*3];struct splay{ int ch[2],fa,st; bool rev;}tree[MAXN*3];int num(int x,int y) {return x*n-n+y;}void insert(int u,int v) { e[++top].u=u;e[top].v=v;tree[top].st=top;}bool is_root(int x) {return tree[tree[x].fa].ch[0]!=x&&tree[tree[x].fa].ch[1]!=x;}void push_down(int x){ if (tree[x].rev) { tree[tree[x].ch[0]].rev^=1;tree[tree[x].ch[1]].rev^=1; swap(tree[x].ch[0],tree[x].ch[1]); } tree[x].rev=0;}void push_up(int x){ int l=tree[x].ch[0],r=tree[x].ch[1];tree[x].st=x; if (l&&e[tree[l].st].w.front()<e[tree[x].st].w.front()) tree[x].st=tree[l].st; if (r&&e[tree[r].st].w.front()<e[tree[x].st].w.front()) tree[x].st=tree[r].st;}void rot(int x){ int y=tree[x].fa,z=tree[y].fa,l,r; l=(tree[y].ch[1]==x);r=l^1; if (!is_root(y)) tree[z].ch[tree[z].ch[1]==y]=x; tree[x].fa=z;tree[y].fa=x;tree[tree[x].ch[r]].fa=y; tree[y].ch[l]=tree[x].ch[r];tree[x].ch[r]=y; push_up(y);push_up(x);}void Splay(int x){ sta[++T]=x; for (int i=x;!is_root(i);i=tree[i].fa) sta[++T]=tree[i].fa; while (T) push_down(sta[T--]); while (!is_root(x)) { int y=tree[x].fa,z=tree[y].fa; if (!is_root(y)) { if ((tree[z].ch[0]==y)^(tree[y].ch[0]==x)) rot(x); else rot(y); } rot(x); }}void access(int x){ for (int i=0;x;i=x,x=tree[x].fa) Splay(x),tree[x].ch[1]=i,push_up(x);}void make_root(int x){ access(x);Splay(x);tree[x].rev^=1;}void link(int x,int y){ make_root(x);tree[x].fa=y;}/*void cut(int x,int y){ make_root(x);access(y);Splay(y);tree[y].ch[0]=tree[x].fa=0;push_up(y);}*/bool cut(int x,int y){ make_root(x);access(y);Splay(y); if (tree[y].ch[0]!=x||tree[x].ch[1]!=0) return 0; tree[y].ch[0]=tree[x].fa=0;push_up(y);return 1;}void split(int x,int y){ make_root(x);access(y);Splay(y);}int find(int x){ access(x);Splay(x); for (;tree[x].ch[0];x=tree[x].ch[0]); return x;}void add(int x,int col){ int u=e[x].u,v=e[x].v; if (find(u)!=find(v)) link(u,x),link(v,x),ans[col]--; else { split(u,v);int y=tree[v].st; if (e[y].w.front()<e[x].w.front()) cut(e[y].u,y),cut(e[y].v,y),link(e[x].u,x),link(e[x].v,x); }}void del(int x,int col){ int u=e[x].u,v=e[x].v; if (cut(x,u)&&cut(x,v)) ans[col]++; e[x].w.pop();}struct Query {short x,y;}q[10010];bool in_size(int x,int y) {return !(x<=0||y<=0||x>n||y>n);}int main(){ in(n);int x,y; for (int i=1;i<=n*n;i++) insert(0,0),e[top].w.push(10010); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) in(a[i][j]),tree[num(i,j)].st=Top; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) insert(num(i,j),num(i,j+1)); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) insert(num(i,j),num(i+1,j)); in(m); for (int i=1;i<=m;i++) { in(x);in(y);q[i]=(Query){(short)x,(short)y}; for (int j=1;j<=4;j++) { int tx=x+dx[j],ty=y+dy[j]; if (!in_size(tx,ty)) continue; if (a[x][y]==a[tx][ty]) e[min(num(x,y),num(tx,ty))+(((j-1)>>1)+1)*n*n].w.push(i); } a[x][y]^=1; } for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { int tx=i,ty=j+1; if (in_size(tx,ty)&&a[i][j]==a[tx][ty]) e[num(i,j)+n*n].w.push(m+1); tx=i+1;ty=j; if (in_size(tx,ty)&&a[i][j]==a[tx][ty]) e[num(i,j)+(n*n<<1)].w.push(m+1); } for (int i=m;i;i--) a[q[i].x][q[i].y]^=1; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) ans[a[i][j]]++; int cnt=0; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { int tx=i,ty=j+1; if (in_size(tx,ty)&&a[i][j]==a[tx][ty]) add(num(i,j)+n*n,a[i][j]),cnt++; tx=i+1;ty=j; if (in_size(tx,ty)&&a[i][j]==a[tx][ty]) add(num(i,j)+(n*n<<1),a[i][j]),cnt++; } for (int i=1;i<=m;i++) { x=q[i].x;y=q[i].y; for (int j=1;j<=4;j++) { int tx=x+dx[j],ty=y+dy[j]; if (in_size(tx,ty)&&a[x][y]==a[tx][ty]) del(min(num(x,y),num(tx,ty))+(((j-1)>>1)+1)*n*n,a[x][y]); } ans[a[x][y]]--;a[x][y]^=1;ans[a[x][y]]++; for (int j=1;j<=4;j++) { int tx=x+dx[j],ty=y+dy[j]; if (in_size(tx,ty)&&a[x][y]==a[tx][ty]) add(min(num(x,y),num(tx,ty))+(((j-1)>>1)+1)*n*n,a[x][y]); } printf("%d %d\n",ans[1],ans[0]); }}
1 0
- 【WC2005】【BZOJ1453】Dface双面棋盘
- BZOJ1453: [Wc]Dface双面棋盘
- bzoj1453: [Wc]Dface双面棋盘
- BZOJ1453——[Wc]Dface双面棋盘
- [BZOJ1453][Wc]Dface双面棋盘(lct)
- BZOJ 1453 Wc2005 Dface双面棋盘 Link-Cut-Tree
- BZOJ1453 WCDface 双面棋盘
- 【BZOJ】【P1453】【WC2005】【Dface双面棋盘】【题解】【线段树+并查集】
- [Wc]Dface双面棋盘
- WC 2005 dface 双面棋盘
- 1453: [Wc]Dface双面棋盘 (线段树+并茶几)
- [CDQ分治 并查集] BZOJ 1453 [Wc]Dface双面棋盘
- BZOJ 1453 [WC] 双面棋盘 并查集+线段树暴搞
- bzoj 1453 双面棋盘 LCT 并查集
- 双面光照
- 双面打印
- COGS 1580 WC2005 友好的生物
- [枚举] COGS 1580 [WC2005]友好的生物
- C#中为何要使用ref参数 (个人理解)
- 如何编写测试报告
- LeetCode Search a 2D Matrix
- oracle第2天之sql
- 10大基础实用算法及其图解(程序员必备)
- 【WC2005】【BZOJ1453】Dface双面棋盘
- spring IOC
- Java使用socket网络编程实现多人聊天室
- JSTL之数字、日期格式化<fmt:formatNumber/>、<fmt:formatDate/>
- 1832: [AHOI2008]聚会 LCA
- java中接口和类【转】
- JSON数据的格式及使用
- 大学三年所学总结之数据库
- 寒假小记