Tree hdu5002

来源:互联网 发布:淘宝送手机充值卡 编辑:程序博客网 时间:2024/06/10 23:01

题意:

很简单的英文自己看,要是这么简单都看不懂以后怎么办?

废话:

感觉我这个人就十分不适合写lct
今天一个傻逼错误调了一下午。。
昨天的lct比别人慢了10倍。。
今天的lct调到死后WA了。。
静态查错+对拍一辈子没弄出来
我的不靠谱对拍。。(极限生成慢,但大数据还是没问题)

#include<cstdio>#include<cstdlib>#include<ctime>#include<cstring>using namespace std;typedef long long LL;const int N=100005;int n,m;struct qq{    int x,y; }s[N];int f[N];int find (int x){    return f[x]==x?f[x]:f[x]=find(f[x]);}int main(){    printf("3\n");    for (int TT=1;TT<=3;TT++)    {    srand(time(0));    n=100;m=100;    printf("%d %d\n",n,m);    for (int u=1;u<=n;u++) printf("%d ",rand()%10+1);    printf("\n");    for (int u=1;u<=n;u++) f[u]=u;    for (int u=1;u<n;u++)    {        int x=rand()%n+1,y=rand()%n+1;        if (find(x)==find(y)) {u--;continue;}        s[u].x=x;s[u].y=y;        printf("%d %d\n",x,y);        f[find(x)]=find(y);    }    for (int u=1;u<=m;u++)    {        int op=rand()%4+1;        printf("%d ",op);        if (op==1)        {            int t=rand()%(n-1)+1;            printf("%d %d ",s[t].x,s[t].y);            for (int u=1;u<=n;u++) f[u]=u;            for (int u=1;u<n;u++)            {                if (u==t) continue;                int fx=find(s[u].x),fy=find(s[u].y);                f[fx]=fy;            }            while (true)            {                int x=rand()%n+1,y=rand()%n+1;                if (find(x)==find(y)) continue;                s[t].x=x;s[t].y=y;                break;            }            printf("%d %d\n",s[t].x,s[t].y);        }        if (op==2||op==3)            printf("%d %d %d\n",rand()%n+1,rand()%n+1,rand()%10+1);        if (op==4)            printf("%d %d\n",rand()%n+1,rand()%n+1);    }}       return 0;}`#include<cstdio>#include<cstring>#include<stack>#include<iostream>using namespace std;const int MAX=1<<30;const int N=100005;int T;int n,m;struct qq{    int son[2],fa;    bool rev;    int mx1,mx2;//最大值    次大值    int num1,num2;//个数    int lalal;//是否全部变成了某个数    -1:没有    int add;//add的中文:加     int tot;//人数    int d;//这个点的值     void bt (int x)    {        d=x;        son[0]=son[1]=fa=rev=0;        mx1=x;num1=1;        mx2=-MAX;num2=0;        lalal=-1;        add=0;tot=1;    };}s[N];void solve (int x,int c,int tot)//我要更新的节点{    if (tot==0) return ;    if (s[x].mx1<c)     {        s[x].mx2=s[x].mx1;/********/        s[x].num2=s[x].num1;/********/        s[x].mx1=c;        s[x].num1=tot;    }    else if (s[x].mx1==c) s[x].num1+=tot;    else if (s[x].mx2<c) {s[x].mx2=c;s[x].num2=tot;}    else if (s[x].mx2==c) s[x].num2+=tot;}void update (int x){    int s1=s[x].son[0],s2=s[x].son[1];    s[x].tot=s[s1].tot+s[s2].tot+1;    /*更新最大次大值以及他们的个数*/    s[x].mx1=s[x].d;s[x].num1=1;    s[x].mx2=-MAX;s[x].num2=0;    if (s1!=0) solve(x,s[s1].mx1,s[s1].num1),solve(x,s[s1].mx2,s[s1].num2);    if (s2!=0) solve(x,s[s2].mx1,s[s2].num1),solve(x,s[s2].mx2,s[s2].num2);    /*更新最大次大值以及他们的个数*/}void change (int x,int c)//全部变成了c {    if (x==0) return ;    s[x].lalal=c;s[x].d=c;s[x].add=0;    s[x].mx1=c;s[x].num1=s[x].tot;    s[x].mx2=-MAX;s[x].num2=0;}void ADD (int x,int c){    if (x==0) return ;    s[x].d+=c;    s[x].add+=c;    s[x].mx1+=c;    if (s[x].mx2!=-MAX) s[x].mx2+=c;}void Push_down(int x){    if (x==0) return ;    int s1=s[x].son[0],s2=s[x].son[1];    if (s[x].lalal!=-1)    {        change(s1,s[x].lalal);change(s2,s[x].lalal);        s[x].lalal=-1;    }    if (s[x].add!=0)    {        int Add=s[x].add;s[x].add=0;        ADD(s1,Add);ADD(s2,Add);    }    if (s[x].rev)    {        s[x].rev=false;        s[s1].rev^=1;s[s2].rev^=1;        swap(s[x].son[0],s[x].son[1]);    }}bool Is_root(int x){  if((s[s[x].fa].son[0]!=x)&&(s[s[x].fa].son[1]!=x)) return true;  return false;}void rotate (int x){    int y=s[x].fa,z=s[y].fa;    int a=s[y].son[1]==x,b=s[z].son[1]==y;    int g=s[x].son[a^1];    if (!Is_root(y)) s[z].son[b]=x;s[x].fa=z;    s[x].son[a^1]=y; s[y].fa=x;    s[y].son[a]=g; if (g!=0) s[g].fa=y;    update(y);update(x);}stack<int> S;void Preserve(int x){    int top=0;    while(!Is_root(x)) S.push(x),x=s[x].fa;S.push(x);    while(!S.empty()) Push_down(S.top()),S.pop();}void Splay (int x){    Preserve(x);    while (!Is_root(x))    {        int y=s[x].fa,z=s[y].fa;        if (Is_root(y)) rotate(x);        else        {            if ((s[y].son[1]==x)==(s[z].son[1]==y)) rotate(y);            else rotate(x);            rotate(x);        }    }    /*printf("\n");    for (int u=1;u<=3;u++)            printf("%d d:%d fa:%d mx1:%d num1:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].tot,s[u].son[0],s[u].son[1]);    printf("%d\n",x);    printf("\n");*/   // update(x);/*    for (int u=1;u<=3;u++)            printf("%d d:%d fa:%d mx1:%d num1:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].tot,s[u].son[0],s[u].son[1]);*/}void Access (int x){    int last=0;    while (x!=0)    {        Splay(x);        s[x].son[1]=last;        update(x);        last=x;        x=s[x].fa;    }}void Make_root (int x){    Access(x);    Splay(x);    s[x].rev^=1;}void Link (int x,int y){    Make_root(x);    s[x].fa=y;}void Split (int x,int y){    Make_root(x);    /*for (int u=1;u<=3;u++)            printf("%d d:%d fa:%d mx1:%d num1:%d mx2:%d num2:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].mx2,s[u].num2,s[u].tot,s[u].son[0],s[u].son[1]);*/    Access(y);    /*printf("\nYES\n");    for (int u=1;u<=3;u++)            printf("%d d:%d fa:%d mx1:%d num1:%d mx2:%d num2:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].mx2,s[u].num2,s[u].tot,s[u].son[0],s[u].son[1]);*/    Splay(y);}void Cut (int x,int y){    Split(x,y);    s[x].fa=0;s[y].son[0]=0;/*******/    update(y);    /*printf("%d %d\n",x,y);    for (int u=1;u<=n;u++)      printf("%d fa:%d s1:%d s2:%d\n",u,s[u].fa,s[u].son[0],s[u].son[1]);*/}inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int main(){    T=read();    for (int fyc=1;fyc<=T;fyc++)    {        printf("Case #%d:\n",fyc);        n=read();m=read();        for (int u=1;u<=n;u++)            s[u].bt(read());        for (int u=1;u<n;u++)        {            int x=read(),y=read();            Link(x,y);        }        for (int u=1;u<=m;u++)        {            int op=read();            if (op==1)//link和cut             {                int x,y;                x=read();y=read();Cut(x,y);                x=read();y=read();Link(x,y);            }            if (op==2)//将x->y这条路径都变成c             {                int x,y,c;                x=read();y=read();c=read();                Split(x,y);                change(y,c);            }            if (op==3)            {                int x,y,c;                x=read();y=read();c=read();                Split(x,y);                ADD(y,c);            }            if (op==4)            {                int x,y;                x=read();y=read();                Split(x,y);                //printf("%d %d %d %d\n",s[y].mx1,s[y].num1,s[y].mx2,s[y].num2);                if (s[y].num2==0) printf("ALL SAME\n");                else printf("%d %d\n",s[y].mx2,s[y].num2);            }            /*for (int u=1;u<=n;u++)            printf("%d fa:%d s1:%d s2:%d\n",u,s[u].fa,s[u].son[0],s[u].son[1]);*/        }    }    return 0;}`

题解

不知道我有没有资格写题解,应该还是有的吧。。
就是一个裸的LCT
维护一堆值,具体看代码,要说的太多。。
全部变量在代码都有注释的,这个可以放心,觉得看得懂。。
然后部分语句也有注释。。
要是有哪一个dalao赏脸拿去对拍,非常欢迎啊
要是发现我WA的数据可以给我,十分欢迎。。
我实在是拍不出了

代码

#include<cstdio>#include<cstring>#include<stack>#include<iostream>using namespace std;const int MAX=1<<30;const int N=100005;int T;int n,m;struct qq{    int son[2],fa;    bool rev;    int mx1,mx2;//最大值    次大值    int num1,num2;//个数    int lalal;//是否全部变成了某个数    -1:没有    int add;//add的中文:加     int tot;//人数    int d;//这个点的值     void bt (int x)    {        d=x;        son[0]=son[1]=fa=rev=0;        mx1=x;num1=1;        mx2=-MAX;num2=0;        lalal=-1;        add=0;tot=1;    };}s[N];void solve (int x,int c,int tot)//我要更新的节点{    if (tot==0) return ;    if (s[x].mx1<c)     {        s[x].mx2=s[x].mx1;/********/        s[x].num2=s[x].num1;/********/        s[x].mx1=c;        s[x].num1=tot;    }    else if (s[x].mx1==c) s[x].num1+=tot;    else if (s[x].mx2<c) {s[x].mx2=c;s[x].num2=tot;}    else if (s[x].mx2==c) s[x].num2+=tot;}void update (int x){    int s1=s[x].son[0],s2=s[x].son[1];    s[x].tot=s[s1].tot+s[s2].tot+1;    /*更新最大次大值以及他们的个数*/    s[x].mx1=s[x].d;s[x].num1=1;    s[x].mx2=-MAX;s[x].num2=0;    if (s1!=0) solve(x,s[s1].mx1,s[s1].num1),solve(x,s[s1].mx2,s[s1].num2);    if (s2!=0) solve(x,s[s2].mx1,s[s2].num1),solve(x,s[s2].mx2,s[s2].num2);    /*更新最大次大值以及他们的个数*/}void change (int x,int c)//全部变成了c {    if (x==0) return ;    s[x].lalal=c;s[x].d=c;s[x].add=0;    s[x].mx1=c;s[x].num1=s[x].tot;    s[x].mx2=-MAX;s[x].num2=0;}void ADD (int x,int c){    if (x==0) return ;    s[x].d+=c;    s[x].add+=c;    s[x].mx1+=c;    if (s[x].mx2!=-MAX) s[x].mx2+=c;}void Push_down(int x){    if (x==0) return ;    int s1=s[x].son[0],s2=s[x].son[1];    if (s[x].lalal!=-1)    {        change(s1,s[x].lalal);change(s2,s[x].lalal);        s[x].lalal=-1;    }    if (s[x].add!=0)    {        int Add=s[x].add;s[x].add=0;        ADD(s1,Add);ADD(s2,Add);    }    if (s[x].rev)    {        s[x].rev=false;        s[s1].rev^=1;s[s2].rev^=1;        swap(s[x].son[0],s[x].son[1]);    }}bool Is_root(int x){  if((s[s[x].fa].son[0]!=x)&&(s[s[x].fa].son[1]!=x)) return true;  return false;}void rotate (int x){    int y=s[x].fa,z=s[y].fa;    int a=s[y].son[1]==x,b=s[z].son[1]==y;    int g=s[x].son[a^1];    if (!Is_root(y)) s[z].son[b]=x;s[x].fa=z;    s[x].son[a^1]=y; s[y].fa=x;    s[y].son[a]=g; if (g!=0) s[g].fa=y;    update(y);update(x);}stack<int> S;void Preserve(int x){    int top=0;    while(!Is_root(x)) S.push(x),x=s[x].fa;S.push(x);    while(!S.empty()) Push_down(S.top()),S.pop();}void Splay (int x){    Preserve(x);    while (!Is_root(x))    {        int y=s[x].fa,z=s[y].fa;        if (Is_root(y)) rotate(x);        else        {            if ((s[y].son[1]==x)==(s[z].son[1]==y)) rotate(y);            else rotate(x);            rotate(x);        }    }    /*printf("\n");    for (int u=1;u<=3;u++)            printf("%d d:%d fa:%d mx1:%d num1:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].tot,s[u].son[0],s[u].son[1]);    printf("%d\n",x);    printf("\n");*/   // update(x);/*    for (int u=1;u<=3;u++)            printf("%d d:%d fa:%d mx1:%d num1:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].tot,s[u].son[0],s[u].son[1]);*/}void Access (int x){    int last=0;    while (x!=0)    {        Splay(x);        s[x].son[1]=last;        update(x);        last=x;        x=s[x].fa;    }}void Make_root (int x){    Access(x);    Splay(x);    s[x].rev^=1;}void Link (int x,int y){    Make_root(x);    s[x].fa=y;}void Split (int x,int y){    Make_root(x);    /*for (int u=1;u<=3;u++)            printf("%d d:%d fa:%d mx1:%d num1:%d mx2:%d num2:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].mx2,s[u].num2,s[u].tot,s[u].son[0],s[u].son[1]);*/    Access(y);    /*printf("\nYES\n");    for (int u=1;u<=3;u++)            printf("%d d:%d fa:%d mx1:%d num1:%d mx2:%d num2:%d tot:%d s1:%d s2:%d\n",u,s[u].d,s[u].fa,s[u].mx1,s[u].num1,s[u].mx2,s[u].num2,s[u].tot,s[u].son[0],s[u].son[1]);*/    Splay(y);}void Cut (int x,int y){    Split(x,y);    s[x].fa=0;s[y].son[0]=0;/*******/    update(y);    /*printf("%d %d\n",x,y);    for (int u=1;u<=n;u++)      printf("%d fa:%d s1:%d s2:%d\n",u,s[u].fa,s[u].son[0],s[u].son[1]);*/}inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int main(){    T=read();    for (int fyc=1;fyc<=T;fyc++)    {        printf("Case #%d:\n",fyc);        n=read();m=read();        for (int u=1;u<=n;u++)            s[u].bt(read());        for (int u=1;u<n;u++)        {            int x=read(),y=read();            Link(x,y);        }        for (int u=1;u<=m;u++)        {            int op=read();            if (op==1)//link和cut             {                int x,y;                x=read();y=read();Cut(x,y);                x=read();y=read();Link(x,y);            }            if (op==2)//将x->y这条路径都变成c             {                int x,y,c;                x=read();y=read();c=read();                Split(x,y);                change(y,c);            }            if (op==3)            {                int x,y,c;                x=read();y=read();c=read();                Split(x,y);                ADD(y,c);            }            if (op==4)            {                int x,y;                x=read();y=read();                Split(x,y);                //printf("%d %d %d %d\n",s[y].mx1,s[y].num1,s[y].mx2,s[y].num2);                if (s[y].num2==0) printf("ALL SAME\n");                else printf("%d %d\n",s[y].mx2,s[y].num2);            }            /*for (int u=1;u<=n;u++)            printf("%d fa:%d s1:%d s2:%d\n",u,s[u].fa,s[u].son[0],s[u].son[1]);*/        }    }    return 0;}
原创粉丝点击