您的位置:首页 > 其它

【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↓

#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]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LCT 动态图