【WC2005】【BZOJ1453】Dface双面棋盘
2016-01-21 19:52
447 查看
Description
Input
Output
Sample Input
Sample Output
HINT
Source
动态图问题(和徐寅展讲的不一样,这个事可以离线的)
LCT维护删除时间的最大生成树,和4025一个姿势
注意Cut时候判断一下是不是要更改答案
我的LCT因为姿势不优美一开始MLE了
蟹蟹雅礼中学的Dashgua君帮我改了改姿势QwQ
AC code↓
MLE code↓
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]); } }
相关文章推荐
- go语言制作一个gif动态图
- [BZOJ2594][WC2006][LCT][MST]水管局长数据加强版
- 【LCT】BZOJ2049[Sdoi2008]Cave 洞穴勘测
- 在Wpf中使用动态GIF图像的简单方法
- 将一组图片播放成动态图
- SPOJ QTREE LCT
- BZOJ1180 [CROATIAN2009]OTOCI
- 自定义view 使用canvas画动态图
- bzoj2049: [Sdoi2008]Cave 洞穴勘测
- bzoj-2001 City 城市建设
- bzoj-2555 SubString
- bzoj-1180 OTOCI
- Aizu 2450 Do use segment tree LCT
- 【NOI2014】【BZOJ3669】魔法森林
- 【WC2006】【BZOJ2594】水管局长数据加强版
- 【BZOJ4025】二分图
- 【SDOI2014】【BZOJ3531】旅行
- 论在LCT上下放标记
- BZOJ 2001 Hnoi2010 城市建设 分治+LCT
- LCT(Link Cut Tree)学习小记