zoukankan      html  css  js  c++  java
  • 【Learning】Link-Cut Tree 题目汇总

    这篇博客主要是记录了我Link-Cut Tree的做题记录。
    推荐一个非常好的博客。orz DTZ学长 %%%%%%%
    http://www.cnblogs.com/RogerDTZ/p/7436469.html
    T1 bzoj2049

    #include<cstdio>
    #include<algorithm>
    using namespace std; 
    int n,m,u,v,fa[10005],ch[10005][2];
    char s[20];
    bool rev[10005];
    bool isroot(int u){
        return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
    }
    int which(int u){
        return ch[fa[u]][1]==u;
    }
    void reverse(int u){
        rev[u]^=1;
        swap(ch[u][0],ch[u][1]);
    }
    void downtag(int u){
        if(rev[u]){
            if(ch[u][0]){
                reverse(ch[u][0]);
            }
            if(ch[u][1]){
                reverse(ch[u][1]);
            }
            rev[u]=0;
        }
    }
    void pushdown(int u){
        if(!isroot(u)){
            pushdown(fa[u]);
        }
        downtag(u);
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],md=which(x);
        if(!isroot(y)){
            ch[z][which(y)]=x;
        }
        fa[x]=z;
        ch[y][md]=ch[x][!md];
        fa[ch[y][md]]=y;
        ch[x][!md]=y;
        fa[y]=x;
    }
    void splay(int u){
        pushdown(u);
        while(!isroot(u)){
            if(!isroot(fa[u])){
                rotate(which(fa[u])==which(u)?fa[u]:u);
            }
            rotate(u);
        }
    }
    void access(int u){
        for(int v=0;u;v=u,u=fa[u]){
            splay(u);
            ch[u][1]=v;
        }
    }
    void makeroot(int u){
        access(u);
        splay(u);
        reverse(u);
    }
    void link(int u,int v){
        makeroot(u);
        fa[u]=v;
    }
    void cut(int u,int v){
        makeroot(u);
        access(v);
        splay(v);
        fa[u]=0;
        ch[v][0]=0;
    }
    bool isconnect(int u,int v){
        if(u==v){
            return true;
        }
        makeroot(u);
        access(v);
        splay(v);
        return fa[u]!=0;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%s%d%d",s,&u,&v);
            if(s[0]=='C'){
                link(u,v);
            }else if(s[0]=='D'){
                cut(u,v);
            }else{
                if(isconnect(u,v)){
                    puts("Yes");
                }else{
                    puts("No");
                }
            }
        }
        return 0;
    }

    T2 bzoj2002

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=200005;
    int n,m,op,x,y,a[N],ch[N][2],fa[N],siz[N],rev[N];
    bool isroot(int u){
        return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
    }
    int which(int u){
        return u==ch[fa[u]][1];
    }
    void pushup(int u){
        siz[u]=1;
        if(ch[u][0]){
            siz[u]+=siz[ch[u][0]];
        }
        if(ch[u][1]){
            siz[u]+=siz[ch[u][1]];
        }
    }
    void reverse(int u){
        rev[u]^=1;
        swap(ch[u][0],ch[u][1]);
    }
    void downtag(int u){
        if(rev[u]){
            if(ch[u][0]){
                reverse(ch[u][0]);
            }
            if(ch[u][1]){
                reverse(ch[u][1]);
            }
            rev[u]=0;
        }
    }
    void pushdown(int u){
        if(!isroot(u)){
            pushdown(fa[u]);
        }
        downtag(u);
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],md=which(x);
        if(!isroot(y)){
            ch[z][which(y)]=x;
        }
        fa[x]=z;
        ch[y][md]=ch[x][!md];
        fa[ch[y][md]]=y;
        ch[x][!md]=y;
        fa[y]=x;
        pushup(y);
        pushup(x);
    }
    void splay(int u){
        pushdown(u);
        while(!isroot(u)){
            if(!isroot(fa[u])){
                rotate(which(fa[u])==which(u)?fa[u]:u);
            }
            rotate(u);
        }
    }
    void access(int u){
        for(int v=0;u;v=u,u=fa[u]){
            splay(u);
            ch[u][1]=v;
            pushup(u);
        }
    }
    void makeroot(int u){
        access(u);
        splay(u);
        reverse(u);
    }
    void link(int u,int v){
        makeroot(u);
        fa[u]=v;
    }
    void cut(int u,int v){
        makeroot(u);
        access(v);
        splay(v);
        fa[u]=ch[v][0]=0;
        pushup(v);
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            if(i+a[i]<=n){
                a[i]=i+a[i];
            }else{
                a[i]=n+1;
            }
            link(i,a[i]);
        }
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&op,&x);
            x++;
            if(op==1){
                makeroot(n+1);
                access(x);
                splay(x);
                printf("%d
    ",siz[ch[x][0]]);
            }else{
                scanf("%d",&y);
                cut(x,a[x]);
                if(x+y<=n){
                    a[x]=x+y;
                }else{
                    a[x]=n+1;
                }
                link(x,a[x]);
            }
        }
        return 0;
    }

    T3 bzoj2631

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef unsigned int ui;
    const int N=100005;
    const ui mod=51061;
    int n,q,u,v,u2,v2,c,rev[N],fa[N],ch[N][2],siz[N];
    ui val[N],sumv[N],mulv[N],addv[N];
    char s[5];
    bool isroot(int u){
        return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
    }
    int which(int u){
        return ch[fa[u]][1]==u;
    }
    void pushup(int u){
        sumv[u]=val[u];
        siz[u]=1;
        if(ch[u][0]){
            sumv[u]=(sumv[u]+sumv[ch[u][0]])%mod;
            siz[u]+=siz[ch[u][0]];
        }
        if(ch[u][1]){
            sumv[u]=(sumv[u]+sumv[ch[u][1]])%mod;
            siz[u]+=siz[ch[u][1]];
        }
    }
    void reverse(int u){
        rev[u]^=1;
        swap(ch[u][0],ch[u][1]);
    }
    void maintain(int u,ui mul,ui add){
        addv[u]=(addv[u]*mul%mod+add)%mod;
        mulv[u]=mulv[u]*mul%mod;
        val[u]=(val[u]*mul%mod+add)%mod;
        sumv[u]=(sumv[u]*mul%mod+siz[u]*add%mod)%mod;
    }
    void downtag(int u){
        if(mulv[u]!=1||addv[u]){
            if(ch[u][0]){
                maintain(ch[u][0],mulv[u],addv[u]);
            }
            if(ch[u][1]){
                maintain(ch[u][1],mulv[u],addv[u]);
            }
            mulv[u]=1;
            addv[u]=0;
        }
        if(rev[u]){
            if(ch[u][0]){
                reverse(ch[u][0]);
            }
            if(ch[u][1]){
                reverse(ch[u][1]);
            }
            rev[u]=0;
        }
    }
    void pushdown(int u){
        if(!isroot(u)){
            pushdown(fa[u]);
        }
        downtag(u);
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],md=which(x);
        if(!isroot(y)){
            ch[z][which(y)]=x;
        }
        fa[x]=z;
        ch[y][md]=ch[x][!md];
        fa[ch[y][md]]=y;
        ch[x][!md]=y;
        fa[y]=x;
        pushup(y);
        pushup(x);
    }
    void splay(int u){
        pushdown(u);
        while(!isroot(u)){
            if(!isroot(fa[u])){
                rotate(which(fa[u])==which(u)?fa[u]:u);
            }
            rotate(u);
        }
    }
    void access(int u){
        for(int v=0;u;v=u,u=fa[u]){
            splay(u);
            ch[u][1]=v;
            pushup(u);
        }
    }
    void makeroot(int u){
        access(u);
        splay(u);
        reverse(u);
    }
    void link(int u,int v){
        makeroot(u);
        fa[u]=v;
    }
    void cut(int u,int v){
        makeroot(u);
        access(v);
        splay(v);
        fa[u]=ch[v][0]=0;
        pushup(v);
    }
    main(){
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++){
            val[i]=sumv[i]=mulv[i]=1;
        }
        for(int i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            link(u,v);
        }
        for(int i=1;i<=q;i++){
            scanf("%s%d%d",s,&u,&v);
            if(s[0]=='+'){
                scanf("%d",&c);
                makeroot(u);
                access(v);
                splay(v);
                maintain(v,1,c);
            }else if(s[0]=='-'){
                scanf("%d%d",&u2,&v2);
                cut(u,v);
                link(u2,v2);
            }else if(s[0]=='*'){
                scanf("%d",&c);
                makeroot(u);
                access(v);
                splay(v);
                maintain(v,c,0);
            }else{
                makeroot(u);
                access(v);
                splay(v);
                printf("%u
    ",sumv[v]);
            }
        }
        return 0;
    }

    T4 bzoj4530

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=100005;
    int n,q,u,v,ch[N][2],fa[N],siz[N],sx[N],rev[N];
    char s[10];
    bool isroot(int u){
        return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
    }
    int which(int u){
        return u==ch[fa[u]][1];
    }
    void pushup(int u){
        siz[u]=sx[u]+1;
        if(ch[u][0]){
            siz[u]+=siz[ch[u][0]];
        }
        if(ch[u][1]){
            siz[u]+=siz[ch[u][1]];
        }
    }
    void reverse(int u){
        rev[u]^=1;
        swap(ch[u][0],ch[u][1]);
    }
    void downtag(int u){
        if(rev[u]){
            if(ch[u][0]){
                reverse(ch[u][0]);
            }
            if(ch[u][1]){
                reverse(ch[u][1]);
            }
            rev[u]=0;
        }
    }
    void pushdown(int u){
        if(!isroot(u)){
            pushdown(fa[u]);
        }
        downtag(u);
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],md=which(x);
        if(!isroot(y)){
            ch[z][which(y)]=x;
        }
        fa[x]=z;
        ch[y][md]=ch[x][!md];
        fa[ch[y][md]]=y;
        ch[x][!md]=y;
        fa[y]=x;
        pushup(y);
        pushup(x);
    }
    void splay(int u){
        pushdown(u);
        while(!isroot(u)){
            if(!isroot(fa[u])){
                rotate(which(fa[u])==which(u)?fa[u]:u);
            }
            rotate(u);
        }
    }
    void access(int u){
        for(int v=0;u;v=u,u=fa[u]){
            splay(u);
            sx[u]+=siz[ch[u][1]]-siz[v];
            ch[u][1]=v;
            pushup(u);
        }
    }
    void makeroot(int u){
        access(u);
        splay(u);
        reverse(u);
    }
    void link(int u,int v){
        makeroot(u);
        makeroot(v);
        fa[u]=v;
        sx[v]+=siz[u];
        pushup(v);
    }
    int main(){
        scanf("%d%d",&n,&q);
        for(int i=1;i<=q;i++){
            scanf("%s%d%d",s,&u,&v);
            if(s[0]=='A'){
                link(u,v);
            }else{
                makeroot(u);
                access(v);
                splay(v);
                printf("%lld
    ",(long long)(siz[u])*(siz[v]-siz[u]));
            }
        }
        return 0;
    }

    T5 bzoj2843&&bzoj1180

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=30005;
    int n,m,u,v,fa[N],val[N],siz[N],sumv[N],rev[N],ch[N][2];
    char s[20];
    bool isroot(int u){
        return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
    }
    int which(int u){
        return u==ch[fa[u]][1];
    }
    void pushup(int u){
        sumv[u]=val[u];
        siz[u]=1;
        if(ch[u][0]){
            sumv[u]+=sumv[ch[u][0]];
            siz[u]+=siz[ch[u][0]];
        }
        if(ch[u][1]){
            sumv[u]+=sumv[ch[u][1]];
            siz[u]+=siz[ch[u][1]];
        }
    }
    void reverse(int u){
        rev[u]^=1;
        swap(ch[u][0],ch[u][1]);
    }
    void downtag(int u){
        if(rev[u]){
            if(ch[u][0]){
                reverse(ch[u][0]);
            }
            if(ch[u][1]){
                reverse(ch[u][1]);
            }
            rev[u]=0;
        }
    }
    void pushdown(int u){
        if(!isroot(u)){
            pushdown(fa[u]);
        }
        downtag(u);
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],md=which(x);
        if(!isroot(y)){
            ch[z][which(y)]=x;
        }
        fa[x]=z;
        ch[y][md]=ch[x][!md];
        fa[ch[y][md]]=y;
        ch[x][!md]=y;
        fa[y]=x;
        pushup(y);
        pushup(x);
    }
    void splay(int u){
        pushdown(u);
        while(!isroot(u)){
            if(!isroot(fa[u])){
                rotate(which(fa[u])==which(u)?fa[u]:u);
            }
            rotate(u);
        }
    }
    void access(int u){
        for(int v=0;u;v=u,u=fa[u]){
            splay(u);
            ch[u][1]=v;
            pushup(u);
        }
    }
    void makeroot(int u){
        access(u);
        splay(u);
        reverse(u);
    }
    void link(int u,int v){
        makeroot(u);
        fa[u]=v;
    }
    bool isconnect(int u,int v){
        if(u==v){
            return true;
        }
        makeroot(u);
        access(v);
        splay(v);
        return fa[u]!=0;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&val[i]);
        }
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            scanf("%s%d%d",s,&u,&v);
            if(s[0]=='b'){
                if(isconnect(u,v)){
                    puts("no");
                }else{
                    puts("yes");
                    link(u,v);
                }
            }else if(s[0]=='p'){
                makeroot(u);
                val[u]=v;
                pushup(u);
            }else{
                if(isconnect(u,v)){
                    makeroot(u);
                    access(v);
                    splay(v);
                    printf("%d
    ",sumv[v]);
                }else{
                    puts("impossible");
                }
            }
        }
        return 0;
    }

    T6 hdu4010

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=300005;
    int n,q,u,v,w,op,cnt,fa[N],ch[N][2],val[N],rev[N],maxv[N],tag[N];
    int uu[N],vv[N];
    void init(){
        memset(fa,0,sizeof(fa));
        memset(ch,0,sizeof(ch));
        memset(val,0,sizeof(val));
        memset(rev,0,sizeof(rev));
        memset(maxv,0,sizeof(maxv));
        memset(tag,0,sizeof(tag));
        cnt=0;
    }
    bool isroot(int u){
        return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
    }
    int which(int u){
        return u==ch[fa[u]][1];
    }
    void pushup(int u){
        maxv[u]=max(val[u],max(maxv[ch[u][0]],maxv[ch[u][1]]));
    }
    void reverse(int u){
        if(!u){
            return;
        }
        rev[u]^=1;
        swap(ch[u][0],ch[u][1]);
    }
    void maintain(int u,int add){
        if(!u){
            return;
        }
        val[u]+=add;
        maxv[u]+=add;
        tag[u]+=add;
    }
    void downtag(int u){
        if(rev[u]){
            reverse(ch[u][0]);
            reverse(ch[u][1]);
            rev[u]=0;
        }
        if(tag[u]){
            maintain(ch[u][0],tag[u]);
            maintain(ch[u][1],tag[u]);
            tag[u]=0;
        }
    }
    void pushdown(int u){
        if(!isroot(u)){
            pushdown(fa[u]);
        }
        downtag(u);
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],md=which(x);
        if(!isroot(y)){
            ch[z][which(y)]=x;
        }
        fa[x]=z;
        ch[y][md]=ch[x][!md];
        fa[ch[y][md]]=y;
        ch[x][!md]=y;
        fa[y]=x;
        pushup(y);
        pushup(x);
    }
    void splay(int u){
        pushdown(u);
        while(!isroot(u)){
            if(!isroot(fa[u])){
                rotate(which(fa[u])==which(u)?fa[u]:u);
            }
            rotate(u);
        }
    }
    void access(int u){
        for(int v=0;u;v=u,u=fa[u]){
            splay(u);
            ch[u][1]=v;
            pushup(u);
        }
    }
    void makeroot(int u){
        access(u);
        splay(u);
        reverse(u);
    }
    void link(int u,int v){
        if(u==v){
            return;
        }
        makeroot(u);
        fa[u]=v;
        if(u==v){
            exit(0);
        }
    }
    void cut(int u,int v){
        if(u==v){
            return;
        }
        makeroot(u);
        access(v);
        splay(v);
        fa[u]=ch[v][0]=0;
        pushup(v);
    }
    bool isconnect(int u,int v){
        if(u==v){
            return true;
        }
        makeroot(u);
        access(v);
        splay(v);
        return fa[u]!=0;
    }
    int main(){
        while(~scanf("%d",&n)){
            init();
            for(int i=1;i<n;i++){
                scanf("%d%d",&uu[i],&vv[i]);
            }
            for(int i=1;i<=n;i++){
                scanf("%d",&val[i]);
                maxv[i]=val[i];
            }
            for(int i=1;i<n;i++){
                link(uu[i],vv[i]);
            }
            scanf("%d",&q);
            for(int i=1;i<=q;i++){
                scanf("%d",&op);
                if(op==1){
                    scanf("%d%d",&u,&v);
                    if(isconnect(u,v)){
                        puts("-1");
                    }else{
                        link(u,v);
                    }
                }else if(op==2){
                    scanf("%d%d",&u,&v);
                    if(!isconnect(u,v)||u==v){
                        puts("-1");
                    }else{
                        cut(u,v);
                    }
                }else if(op==3){
                    scanf("%d%d%d",&w,&u,&v);
                    if(!isconnect(u,v)){
                        puts("-1");
                    }else{
                        makeroot(u);
                        access(v);
                        splay(v);
                        maintain(v,w);
                    }
                }else{
                    scanf("%d%d",&u,&v);
                    if(!isconnect(u,v)){
                        puts("-1");
                    }else{
                        makeroot(u);
                        access(v);
                        splay(v);
                        printf("%d
    ",maxv[v]);
                    }
                }
            }
            puts("");
        }
        return 0;
    }

    T7 bzoj3282

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=300005;
    int n,m,op,u,v,fa[N],ch[N][2],rev[N],val[N],sumv[N];
    bool isroot(int u){
        return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
    }
    int which(int u){
        return u==ch[fa[u]][1];
    }
    void pushup(int u){
        sumv[u]=val[u];
        if(ch[u][0]){
            sumv[u]^=sumv[ch[u][0]];
        }
        if(ch[u][1]){
            sumv[u]^=sumv[ch[u][1]];
        }
    }
    void reverse(int u){
        rev[u]^=1;
        swap(ch[u][0],ch[u][1]);
    }
    void downtag(int u){
        if(rev[u]){
            if(ch[u][0]){
                reverse(ch[u][0]);
            }
            if(ch[u][1]){
                reverse(ch[u][1]);
            }
            rev[u]=0;
        }
    }
    void pushdown(int u){
        if(!isroot(u)){
            pushdown(fa[u]);
        }
        downtag(u);
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],md=which(x);
        if(!isroot(y)){
            ch[z][which(y)]=x;
        }
        fa[x]=z;
        ch[y][md]=ch[x][!md];
        fa[ch[y][md]]=y;
        ch[x][!md]=y;
        fa[y]=x;
        pushup(y);
        pushup(x);
    }
    void splay(int u){
        pushdown(u);
        while(!isroot(u)){
            if(!isroot(fa[u])){
                rotate(which(fa[u])==which(u)?fa[u]:u);
            }
            rotate(u);
        }
    }
    void access(int u){
        for(int v=0;u;v=u,u=fa[u]){
            splay(u);
            ch[u][1]=v;
            pushup(u);
        }
    }
    void makeroot(int u){
        access(u);
        splay(u);
        reverse(u);
    }
    void link(int u,int v){
        makeroot(u);
        fa[u]=v;
    }
    void cut(int u,int v){
        makeroot(u);
        access(v);
        splay(v);
        fa[u]=ch[v][0]=0;
        pushup(v);
    }
    bool isconnect(int u,int v){
        if(u==v){
            return true;
        }
        makeroot(u);
        access(v);
        splay(v);
        return fa[u]!=0;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&val[i]);
            sumv[i]=val[i];
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&op,&u,&v);
            if(op==0){
                makeroot(u);
                access(v);
                splay(v);
                printf("%d
    ",sumv[v]);
            }else if(op==1){
                if(!isconnect(u,v)){
                    link(u,v);
                }
            }else if(op==2){
                if(isconnect(u,v)&&u!=v){
                    cut(u,v);
                }
            }else{
                makeroot(u);
                val[u]=v;
                pushup(u);
            }
        }
        return 0;
    }

    T8 bzoj3669

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=150005,M=150005;
    int n,m,ans=0x7f7f7f7f,fa[N],ch[N][2],rev[N];
    struct edge{
        int u,v,a,b,id;
        bool operator < (const edge &a) const{
            return b<a.b;
        }
    }e[M],val[N],maxv[N];
    bool cmp(edge a,edge b){
        return a.a<b.a;
    }
    bool isroot(int u){
        return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
    }
    int which(int u){
        return u==ch[fa[u]][1];
    }
    void pushup(int u){
        maxv[u]=val[u];
        if(ch[u][0]){
            maxv[u]=max(maxv[u],maxv[ch[u][0]]);
        }
        if(ch[u][1]){
            maxv[u]=max(maxv[u],maxv[ch[u][1]]);
        }
    }
    void reverse(int u){
        rev[u]^=1;
        swap(ch[u][0],ch[u][1]);
    }
    void downtag(int u){
        if(rev[u]){
            if(ch[u][0]){
                reverse(ch[u][0]);
            }
            if(ch[u][1]){
                reverse(ch[u][1]);
            }
            rev[u]=0;
        }
    }
    void pushdown(int u){
        if(!isroot(u)){
            pushdown(fa[u]);
        }
        downtag(u);
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],md=which(x);
        if(!isroot(y)){
            ch[z][which(y)]=x;
        }
        fa[x]=z;
        ch[y][md]=ch[x][!md];
        fa[ch[y][md]]=y;
        ch[x][!md]=y;
        fa[y]=x;
        pushup(y);
        pushup(x);
    }
    void splay(int u){
        pushdown(u);
        while(!isroot(u)){
            if(!isroot(fa[u])){
                rotate(which(fa[u])==which(u)?fa[u]:u);
            }
            rotate(u);
        }
    }
    void access(int u){
        for(int v=0;u;v=u,u=fa[u]){
            splay(u);
            ch[u][1]=v;
            pushup(u);
        }
    }
    void makeroot(int u){
        access(u);
        splay(u);
        reverse(u);
    }
    void link(int u,int v){
        makeroot(u);
        fa[u]=v;
    }
    void cut(int u,int v){
        makeroot(u);
        access(v);
        splay(v);
        fa[u]=ch[v][0]=0;
        pushup(v);
    }
    bool isconnect(int u,int v){
        if(u==v){
            return true;
        }
        makeroot(u);
        access(v);
        splay(v);
        return fa[u]!=0;
    }
    int main(){
        scanf("%d%d",&n,&m);
        if(n==1){
            puts("0");
            return 0;
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].a,&e[i].b);
        }
        sort(e+1,e+m+1,cmp);
        for(int i=1;i<=m;i++){
            e[i].id=i;
            val[i+n]=maxv[i+n]=e[i];
        }
        for(int i=1;i<=m;i++){
            if(!isconnect(e[i].u,e[i].v)){
                link(e[i].u,i+n);
                link(i+n,e[i].v);
            }else if(e[i].u!=e[i].v){
                makeroot(e[i].u);
                access(e[i].v);
                splay(e[i].v);
                edge tmp=maxv[e[i].v];
                if(e[i].b<maxv[e[i].v].b){
                    cut(tmp.u,tmp.id+n);
                    cut(tmp.id+n,tmp.v);
                    link(e[i].u,i+n);
                    link(i+n,e[i].v);
                }
            }
            if(isconnect(1,n)){
                makeroot(1);
                access(n);
                splay(n);
                ans=min(ans,e[i].a+maxv[n].b);
            }
        }
        printf("%d
    ",ans==0x7f7f7f7f?-1:ans);
        return 0;
    }

    T8 bzoj3306
    和遥远的国度一题很像,只不过写了Link-Cut Tree。打了一个Treap。

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    const int N=100005;
    int n,q,rt,f,x,y,a[N],fa[N],rev[N],minv[N],ch[N][2];
    int siz[N*50],w[N*50],val[N*50],rnd[N*50],c[N*50][2],mmp[N*50];
    char s[10];
    struct Treap{
        int root;
        int qmin(){
            int k=root;
            while(c[k][0]){
                k=c[k][0];
            }
            return val[k];
        }
        void pushup(int u){
            siz[u]=w[u]+siz[c[u][0]]+siz[c[u][1]];
        }
        void rotate(int &y,int md){
            int x=c[y][md];
            c[y][md]=c[x][!md];
            c[x][!md]=y;
            pushup(y);
            pushup(x);
            y=x;
        }
        void insert(int &k,int x){
            if(!k){
                k=mmp[mmp[0]--];
                siz[k]=w[k]=1;
                c[k][0]=c[k][1]=0;
                val[k]=x;
                rnd[k]=rand();
                return;
            }
            siz[k]++;
            if(x==val[k]){
                w[k]++;
            }else{
                int md=x>val[k];
                insert(c[k][md],x);
                if(rnd[c[k][md]]<rnd[k]){
                    rotate(k,md);
                }
            }
        }
        void remove(int &k,int x){
            siz[k]--;
            if(x==val[k]){
                if(w[k]>1){
                    w[k]--;
                }else{
                    if(c[k][0]*c[k][1]==0){
                        mmp[++mmp[0]]=k;
                        k=c[k][0]+c[k][1];
                    }else{
                        rotate(k,rnd[c[k][0]]>rnd[c[k][1]]);
                        remove(k,x);
                    }
                }
            }else{
                remove(c[k][x>val[k]],x);
            }
        }
    }set[N];
    bool isroot(int u){
        return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
    }
    int which(int u){
        return u==ch[fa[u]][1];
    }
    int pushup(int u){
        minv[u]=set[u].qmin();
        if(ch[u][0]){
            minv[u]=min(minv[u],minv[ch[u][0]]);
        }
        if(ch[u][1]){
            minv[u]=min(minv[u],minv[ch[u][1]]);
        }
    }
    void reverse(int u){
        rev[u]^=1;
        swap(ch[u][0],ch[u][1]);
    }
    void downtag(int u){
        if(rev[u]){
            if(ch[u][0]){
                reverse(ch[u][0]);
            }
            if(ch[u][1]){
                reverse(ch[u][1]);
            }
            rev[u]=0;
        }
    }
    void pushdown(int u){
        if(!isroot(u)){
            pushdown(fa[u]);
        }
        downtag(u);
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],md=which(x);
        if(!isroot(y)){
            ch[fa[y]][which(y)]=x;
        }
        fa[x]=z;
        ch[y][md]=ch[x][!md];
        fa[ch[y][md]]=y;
        ch[x][!md]=y;
        fa[y]=x;
        pushup(y);
        pushup(x);
    }
    void splay(int u){
        pushdown(u);
        while(!isroot(u)){
            if(!isroot(fa[u])){
                rotate(which(fa[u])==which(u)?fa[u]:u);
            }
            rotate(u);
        }
    }
    void access(int u){
        for(int v=0;u;v=u,u=fa[u]){
            splay(u);
            if(ch[u][1]){
                set[u].insert(set[u].root,minv[ch[u][1]]);
            }
            ch[u][1]=v;
            if(ch[u][1]){
                set[u].remove(set[u].root,minv[ch[u][1]]);
            }
            pushup(u);
        }
    }
    void makeroot(int u){
        access(u);
        splay(u);
        reverse(u);
    }
    int cnt,head[N],to[N],nxt[N];
    void adde(int u,int v){
        to[++cnt]=v;
        nxt[cnt]=head[u];
        head[u]=cnt;
    }
    void dfs(int u){
        int v;
        minv[u]=a[u];
        set[u].insert(set[u].root,a[u]);
        for(int i=head[u];i;i=nxt[i]){
            v=to[i];
            dfs(v);
            fa[v]=u;
            set[u].insert(set[u].root,minv[v]);
        }
        pushup(u);
    }
    int main(){
        for(int i=5000000;i>=1;i--){
            mmp[++mmp[0]]=i;
        }
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&f,&a[i]);
            if(f){
                adde(f,i);
            }else{
                rt=i;
            }
        }
        dfs(rt);
        for(int i=1;i<=q;i++){
            scanf("%s%d",s,&x);
            if(s[0]=='V'){
                scanf("%d",&y);
                access(x);
                splay(x);
                set[x].remove(set[x].root,a[x]);
                a[x]=y;
                set[x].insert(set[x].root,a[x]);
                pushup(x);
            }else if(s[0]=='E'){
                makeroot(x);
            }else{
                access(x);
                splay(x);
                printf("%d
    ",set[x].qmin());
            }
        }
        return 0;
    }

    T9 bzoj2959

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=150005;
    int n,m,op,u,v,fu0,fv0,fu1,fv1,pa[N][2],fa[N],ch[N][2],rev[N],val[N],sumv[N];
    int a[N];
    int find(int u,int md){
        return u==pa[u][md]?u:pa[u][md]=find(pa[u][md],md);
    }
    bool isroot(int u){
        if(!fa[u]){
            return true;
        }
        int tmp=find(fa[u],1);
        return u!=ch[tmp][0]&&u!=ch[tmp][1];
    }
    int which(int u){
        return u==ch[find(fa[u],1)][1];
    }
    void pushup(int u){
        if(!u){
            return;
        }
        sumv[u]=val[u]+sumv[ch[u][0]]+sumv[ch[u][1]];
    }
    void reverse(int u){
        rev[u]^=1;
        swap(ch[u][0],ch[u][1]);
    }
    void downtag(int u){
        if(rev[u]){
            if(ch[u][0]){
                reverse(ch[u][0]);
            }
            if(ch[u][1]){
                reverse(ch[u][1]);
            }
            rev[u]=0;
        }
    }
    void pushdown(int u){
        if(!isroot(u)){
            pushdown(fa[u]);
        }
        downtag(u);
    }
    void rotate(int x){
        int y=find(fa[x],1),z=find(fa[y],1),md=x==ch[y][1];
        if(y==ch[z][0]||y==ch[z][1]){
            ch[z][y==ch[z][1]]=x;
        }
        fa[x]=z;
        ch[y][md]=ch[x][!md];
        if(ch[y][md]){
            fa[ch[y][md]]=y;
        }
        ch[x][!md]=y;
        if(y){
            fa[y]=x;
        }
        pushup(y);
        pushup(x);
    }
    void splay(int u){
        pushdown(u);
        while(!isroot(u)){
            if(!isroot(fa[u])){
                rotate(which(fa[u])==which(u)?fa[u]:u);
            }
            rotate(u);
        }
    }
    void access(int u){
        for(int v=0;u;v=u,u=find(fa[u],1)){
            splay(u);
            ch[u][1]=v;
            pushup(u);
        }
    }
    void makeroot(int u){
        access(u);
        splay(u);
        reverse(u);
    }
    int dfs(int rt,int u){
        if(!u){
            return 0;
        }
        pa[u][1]=rt;
        return dfs(rt,ch[u][0])+dfs(rt,ch[u][1])+val[u];
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            pa[i][0]=pa[i][1]=i;
        }
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            sumv[i]=val[i]=a[i];
        }
        for(int i=1;i<=m;i++){
            if(i==24){
                u++;
            }
            scanf("%d%d%d",&op,&u,&v);
            if(op==1){
                if((fu1=find(u,1))!=(fv1=find(v,1))){
                    if((fu0=find(u,0))!=(fv0=find(v,0))){
                        makeroot(fu1);
                        fa[fu1]=fv1;
                        pa[fv0][0]=fu0;
                    }else{
                        makeroot(fu1);
                        access(fv1);
                        splay(fv1);
                        val[fu1]=dfs(fu1,fv1);
                        fa[fu1]=0;
                        ch[fu1][0]=ch[fu1][1]=0;
                        pushup(fu1);
                    }
                }
            }else if(op==2){
                splay(fu1=find(u,1));
                val[fu1]-=a[u];
                a[u]=v;
                val[fu1]+=a[u];
                pushup(fu1);
            }else{
                if(find(u,0)!=find(v,0)){
                    puts("-1");
                    continue;
                }
                fu1=find(u,1),fv1=find(v,1);
                makeroot(fu1);
                access(fv1);
                splay(fv1);
                printf("%d
    ",sumv[fv1]);
            }
        }
        return 0;
    }

    T10 bzoj2594

    #include<cstdio>
    #include<algorithm>
    #include<set>
    using namespace std;
    inline int rd(){
        char ch=getchar();
        int ret=0,f=1;
        while(ch<'0'||ch>'9'){
            if(ch=='-'){
                f=-1;
            }
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            ret=ret*10+ch-'0';
            ch=getchar();
        }
        return ret*f;
    }
    const int N=100005,M=1000005;
    int n,m,tot,cnt,q,u,v,L[N],R[N],pa[N];
    int head[N+M],to[4*N],nxt[4*N];
    int fa[N+M],ch[N+M][2],rev[N+M],val[N+M],maxn[N+M],stk[N+M];
    int find(int u){
        return u==pa[u]?u:pa[u]=find(pa[u]);
    }
    struct edge{
        int u,v,d,id;
        bool flag;
    }e1[M],e2[M];
    struct operation{
        int op,u,v,ans;
    }op[N];
    bool cmp1(edge a,edge b){
        return a.u==b.u?a.v<b.v:a.u<b.u;
    }
    bool cmp2(edge a,edge b){
        return a.d<b.d;
    }
    void adde(int u,int v){
        to[++cnt]=v;
        nxt[cnt]=head[u];
        head[u]=cnt;
    }
    void dfs(int u){
        int v;
        for(int i=head[u];i;i=nxt[i]){
            v=to[i];
            if(v!=fa[u]){
                fa[v]=u;
                dfs(v);
            }
        }
    }
    int find(int u,int v){
        int l=L[u],r=R[u],mid;
        while(l<=r){
            mid=(l+r)/2;
            if(e1[mid].v<v){
                l=mid+1;
            }else if(e1[mid].v>v){
                r=mid-1;
            }else{
                return mid;
            }
        }
    }
    bool isroot(int u){
        return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
    }
    int which(int u){
        return u==ch[fa[u]][1];
    }
    void pushup(int u){
        if(u>n){
            maxn[u]=u-n;
        }else{
            maxn[u]=0;
        }
        if(e1[maxn[ch[u][0]]].d>e1[maxn[u]].d){
            maxn[u]=maxn[ch[u][0]];
        }
        if(e1[maxn[ch[u][1]]].d>e1[maxn[u]].d){
            maxn[u]=maxn[ch[u][1]];
        }
    }
    void reverse(int u){
        rev[u]^=1;
        swap(ch[u][0],ch[u][1]);
    }
    void downtag(int u){
        if(rev[u]){
            if(ch[u][0]){
                reverse(ch[u][0]);
            }
            if(ch[u][1]){
                reverse(ch[u][1]);
            }
            rev[u]=0;
        }
    }
    void pushdown(int u){
        stk[stk[0]=1]=u;
        for(;!isroot(u);u=fa[u]){
            stk[++stk[0]]=fa[u];
        }
        while(stk[0]){
            downtag(stk[stk[0]--]);
        }
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],md=which(x);
        if(!isroot(y)){
            ch[z][which(y)]=x;
        }
        fa[x]=z;
        ch[y][md]=ch[x][!md];
        fa[ch[y][md]]=y;
        ch[x][!md]=y;
        fa[y]=x;
        pushup(y);
        pushup(x);
    }
    void splay(int u){
        pushdown(u);
        while(!isroot(u)){
            if(!isroot(fa[u])){
                rotate(which(fa[u])==which(u)?fa[u]:u);
            }
            rotate(u);
        }
    }
    void access(int u){
        for(int v=0;u;v=u,u=fa[u]){
            splay(u);
            ch[u][1]=v;
            pushup(u);
        }
    }
    void makeroot(int u){
        access(u);
        splay(u);
        reverse(u);
    }
    void link(int u,int v){
        makeroot(u);
        fa[u]=v;
    }
    void cut(int u,int v){
        makeroot(u);
        access(v);
        splay(v);
        fa[u]=ch[v][0]=0;
        pushup(v);
    }
    int main(){
        n=rd(),m=rd(),q=rd();
        for(int i=1;i<=m;i++){
            e1[i].u=rd(),e1[i].v=rd(),e1[i].d=rd();
            if(e1[i].u>e1[i].v){
                e1[i].u^=e1[i].v;
                e1[i].v^=e1[i].u;
                e1[i].u^=e1[i].v;
            }
        }
        sort(e1+1,e1+m+1,cmp1);
        for(int i=1;i<=m;i++){
            e1[i].id=i;
            maxn[i+n]=i;
        }
        L[1]=1;
        R[n]=m;
        for(int i=2;i<=m;i++){
            if(e1[i].u!=e1[i-1].u){
                L[e1[i].u]=i;
                R[e1[i-1].u]=i-1;
            }
        }
        for(int i=1;i<=q;i++){
            op[i].op=rd(),op[i].u=rd(),op[i].v=rd();
            if(op[i].op==2){
                if(op[i].u>op[i].v){
                    op[i].u^=op[i].v;
                    op[i].v^=op[i].u;
                    op[i].u^=op[i].v;
                }
                u=find(op[i].u,op[i].v);
                e1[u].flag=true;
            }
        }
        for(int i=1;i<=m;i++){
            if(!e1[i].flag){
                e2[++tot]=e1[i];
            }
        }
        sort(e2+1,e2+tot+1,cmp2);
        for(int i=1;i<=n;i++){
            pa[i]=i;
        }
        for(int i=1,j=0;i<=tot&&j!=n-1;i++){
            u=find(e2[i].u),v=find(e2[i].v);
            if(u!=v){
                j++;
                pa[v]=u;
                adde(e2[i].u,e2[i].id+n);
                adde(e2[i].id+n,e2[i].u);
                adde(e2[i].v,e2[i].id+n);
                adde(e2[i].id+n,e2[i].v);
            }
        }
        dfs(1);
        for(int i=q;i>=1;i--){
            if(op[i].op==1){
                makeroot(op[i].u);
                access(op[i].v);
                splay(op[i].v);
                op[i].ans=e1[maxn[op[i].v]].d;
            }else{
                makeroot(op[i].u);
                access(op[i].v);
                splay(op[i].v);
                u=maxn[op[i].v],v=find(op[i].u,op[i].v);
                if(e1[u].d>e1[v].d){
                    cut(e1[u].u,u+n);
                    cut(u+n,e1[u].v);
                    link(e1[v].u,v+n);
                    link(v+n,e1[v].v);
                }
            }
        }
        for(int i=1;i<=q;i++){
            if(op[i].op==1){
                printf("%d
    ",op[i].ans);
            }
        }
        return 0;
    }

    T11 uva11994
    各种乱搞之后终于过了!仍然把边变成点。
    其实我的代码判断祖孙关系非常暴力,可以被卡。暂时没想到怎么在动态树中快速判断祖孙关系==

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=50005;
    int n,m,op,u,v,c,cnt,ans,pa[N],rt[N];
    int fa[N*2],ch[N*2][2],rev[N*2],tag[N*2],sumv[N*2],siz[N*2],val[N*2],stk[N*2]; 
    int head[N*2],to[N*4],nxt[N*4];
    void adde(int u,int v){
        to[++cnt]=v;
        nxt[cnt]=head[u];
        head[u]=cnt;
    }
    void dfs(int u){
        int v;
        for(int i=head[u];i;i=nxt[i]){
            v=to[i];
            if(v!=fa[u]){
                fa[v]=u;
                dfs(v);
            }
        }
    }
    bool isroot(int u){
        return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
    }
    int which(int u){
        return u==ch[fa[u]][1];
    }
    void pushup(int u){
        sumv[u]=1<<val[u];
        siz[u]=1;
        if(ch[u][0]){
            sumv[u]|=sumv[ch[u][0]];
            siz[u]+=siz[ch[u][0]];
        }
        if(ch[u][1]){
            sumv[u]|=sumv[ch[u][1]];
            siz[u]+=siz[ch[u][1]];
        }
    }
    void reverse(int u){
        rev[u]^=1;
        swap(ch[u][0],ch[u][1]);
    }
    void maintain(int u,int c){
        tag[u]=c;
        sumv[u]=1<<c;
        if(u>n){
            val[u]=c;
        }
    }
    void downtag(int u){
        if(rev[u]){
            if(ch[u][0]){
                reverse(ch[u][0]);
            }
            if(ch[u][1]){
                reverse(ch[u][1]);
            }
            rev[u]=0;
        }
        if(tag[u]){
            if(ch[u][0]){
                maintain(ch[u][0],tag[u]);
            }
            if(ch[u][1]){
                maintain(ch[u][1],tag[u]);
            }
            tag[u]=0;
        }
    }
    void pushdown(int u){
        stk[stk[0]=1]=u;
        for(;!isroot(u);u=fa[u]){
            stk[++stk[0]]=fa[u];
        }
        while(stk[0]){
            downtag(stk[stk[0]--]);
        }
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],md=which(x);
        if(!isroot(y)){
            ch[z][which(y)]=x;
        }
        fa[x]=z;
        ch[y][md]=ch[x][!md];
        fa[ch[y][md]]=y;
        ch[x][!md]=y;
        fa[y]=x;
        pushup(y);
        pushup(x);
    }
    void splay(int u){
        pushdown(u);
        while(!isroot(u)){
            if(!isroot(fa[u])){
                rotate(which(fa[u])==which(u)?fa[u]:u);
            }
            rotate(u);
        }
    }
    void access(int u){
        for(int v=0;u;v=u,u=fa[u]){
            splay(u);
            ch[u][1]=v;
            pushup(u);
        }
    }
    void makeroot(int u){
        access(u);
        splay(u);
        reverse(u);
    }
    void link(int u,int v){
        makeroot(u);
        fa[u]=v;
    }
    void cut(int u,int v){
        makeroot(u);
        access(v);
        splay(v);
        fa[u]=ch[v][0]=0;
        pushup(v);
    }
    bool judge(int u,int v){
        while(v){
            if(u==v){
                return false;
            }
            v=pa[v];
        }
        return true;
    }
    bool isconnect(int u,int v){
        if(u==v){
            return true;
        }
        makeroot(u);
        access(v);
        splay(v);
        return fa[u]!=0;
    }
    int main(){
        while(~scanf("%d%d",&n,&m)){
            memset(fa,0,sizeof(fa));
            memset(ch,0,sizeof(ch));
            memset(rev,0,sizeof(rev));
            memset(tag,0,sizeof(tag));
            memset(sumv,0,sizeof(sumv));
            memset(siz,0,sizeof(siz));
            memset(val,0,sizeof(val));
            memset(head,0,sizeof(head));
            rt[0]=cnt=0;
            for(int i=1;i<=n;i++){
                scanf("%d",&pa[i]);
                if(pa[i]){
                    adde(pa[i],i+n);
                    adde(i+n,pa[i]);
                    adde(i,i+n);
                    adde(i+n,i);
                }else{
                    rt[++rt[0]]=i;
                }
            }
            for(int i=1;i<=n;i++){
                scanf("%d",&val[i+n]);
                sumv[i+n]=1<<val[i+n];
                siz[i]=siz[i+n]=1;
            }
            for(int i=1;i<=rt[0];i++){
                dfs(rt[i]);
            }
            for(int i=1;i<=m;i++){
                scanf("%d%d%d",&op,&u,&v);
                if(op==1){
                    scanf("%d",&c);
                    if(judge(u,v)){
                        if(pa[u]){
                            cut(pa[u],u+n);
                            cut(u+n,u);
                        }
                        pa[u]=v;
                        link(pa[u],u+n);
                        link(u+n,u);
                        splay(u+n);
                        val[u+n]=c;
                        pushup(u+n);
                    }
                }else if(op==2){
                    scanf("%d",&c);
                    if(u!=v&&isconnect(u,v)){
                        makeroot(u);
                        access(v);
                        splay(v);
                        maintain(v,c);
                    }
                }else{
                    if(u==v||!isconnect(u,v)){
                        puts("0 0");
                    }else{
                        makeroot(u);
                        access(v);
                        splay(v);
                        ans=0;
                        for(int j=1;j<=30;j++){
                            if(sumv[v]&(1<<j)){
                                ans++;
                            }
                        }
                        printf("%d %d
    ",(siz[v]-1)/2,ans);
                    }
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    VBScript的参数引用
    异常处理规范
    测试感悟
    URL重写
    避免重复记录
    EJB 异常处理探试法
    EJB 异常处理的最佳做法(1)
    使用vbscript脚本调用web服务
    用Dom4j解析XML及中文问题
    lucene简介
  • 原文地址:https://www.cnblogs.com/2016gdgzoi471/p/9476912.html
Copyright © 2011-2022 走看看