【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
原创粉丝点击