hdu 4010 Query on The Trees LCT

支持:
1.添加边 x,y
2.删边 x,y
3.对于路径x,y上的所有节点的值加上w
4.询问路径x,y上的所有节点的最大权值

分析:
裸的lct...
rev忘了清零死循环了两小时。。。

1:就是link操作

2:就是cut操作

3:维护多一个mx域,mx[x]表示在splay中以节点x为根的子树的最大点权,每次修改时,把x置为splay的根,打通y到x的路径,把y splay到根,那么,直接对y节点的lazy标记加上为w即可。

4:同3操作,把x置为splay的根,打通y到x的路径,把y splay到根,那么,y子树所对应的节点就是路径x到y的所有节点。

 

另外,题目貌似描述有点问题,不光是询问非法输出-1,是指操作如果是非法就输出-1....

 

#include <set>

#include <map>

#include <list>

#include <cmath>

#include <queue>

#include <stack>

#include <string>

#include <vector>

#include <cstdio>

#include <cstring>

#include <iostream>

#include <algorithm>



using namespace std;



typedef long long ll;

typedef unsigned long long ull;



#define debug puts("here")

#define rep(i,n) for(int i=0;i<n;i++)

#define rep1(i,n) for(int i=1;i<=n;i++)

#define REP(i,a,b) for(int i=a;i<=b;i++)

#define foreach(i,vec) for(unsigned i=0;i<vec.size();i++)

#define pb push_back

#define RD(n) scanf("%d",&n)

#define RD2(x,y) scanf("%d%d",&x,&y)

#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)

#define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)

#define All(vec) vec.begin(),vec.end()

#define MP make_pair

#define PII pair<int,int>

#define PQ priority_queue

#define cmax(x,y) x = max(x,y)

#define cmin(x,y) x = min(x,y)

#define Clear(x) memset(x,0,sizeof(x))

/*



#pragma comment(linker, "/STACK:1024000000,1024000000")



int size = 256 << 20; // 256MB

char *p = (char*)malloc(size) + size;

__asm__("movl %0, %%esp\n" :: "r"(p) );



*/



/******** program ********************/



const int MAXN = 3e5+5;



// 外挂

char op;

inline void Int(int &x){

    while( !isdigit(op=getchar()) );

    x = op-'0';

    while(isdigit(op=getchar()))

        x = x*10+op-'0';

}



struct LCT{

    int ch[MAXN][2],fa[MAXN];

    int lz[MAXN],mx[MAXN],val[MAXN];

    bool rev[MAXN];

    int sta[MAXN],top;



    inline void init(){

        Clear(ch);

        Clear(fa);

        Clear(lz);

        Clear(rev);

        mx[0] = 0;

    }



    inline void modify(int x,int d){ // 单点增加lazy标记

        if(!x)return;

        lz[x] += d;

        mx[x] += d;

        val[x] += d;

    }



    inline void clear(int x){

        if(!x)return;

        if(rev[x]){

            if(ch[x][0])rev[ch[x][0]] ^= 1;

            if(ch[x][1])rev[ch[x][1]] ^= 1;

            swap(ch[x][0],ch[x][1]);

            rev[x] = 0;

        }

        if(lz[x]){

            modify(ch[x][0],lz[x]);

            modify(ch[x][1],lz[x]);

            lz[x] = 0;

        }

    }



    inline void update(int x){

        if(!x)return;

        mx[x] = max( val[x],max(mx[ch[x][0]],mx[ch[x][1]]) );

    }



    inline bool isRoot(int x){

        return !x || !( (ch[ fa[x] ][0]==x) || (ch[ fa[x] ][1]==x) );

    }



    inline bool sgn(int x){

        return ch[ fa[x] ][1]==x;

    }

    inline void setc(int y,int d,int x){

        ch[y][d] = x;

        fa[x] = y;

    }

    inline void rot(int x){

        int y = fa[x] , z = fa[y] , d = sgn(x)^1;

        setc(y,d^1,ch[x][d]);

        if(isRoot(y)) fa[x] = fa[y];

        else setc(z,sgn(y),x);

        setc(x,d,y);

        update(y);

    }



    inline void splay(int x){

        if(!x)return;

        top = 0;

        sta[++top] = x;

        for(int y=x;!isRoot(y);y=fa[y])

            sta[++top] = fa[y];

        while(top)clear(sta[top--]);



        while(!isRoot(x)){

            if(isRoot(fa[x]))rot(x);

            else{

                sgn(x)==sgn(fa[x]) ? rot(fa[x]) : rot(x);

                rot(x);

            }

        }

        update(x);

    }



    inline int access(int x){

        int y = 0;

        for(;x;x=fa[y = x]){

            splay(x);

            ch[x][1] = y;

            update(x);

        }

        return y;

    }



    inline void mRoot(int x){

        rev[ access(x) ] ^= 1;

        splay(x);

    }



    inline int getRoot(int x){

        x = access(x);

        while(ch[x][0]){

            x = ch[x][0];

            clear(x);

        }

        return x;

    }



    inline bool jud(int x,int y){// ok

        return getRoot(x)==getRoot(y);

    }



    inline void link(int x,int y){

        if(jud(x,y)){

            puts("-1");

            return;

        }

        mRoot(x);

        fa[x] = y;

        //access(x);

    }



    inline void cut(int x,int y){

        if(x==y||!jud(x,y)){

            puts("-1");

            return;

        }

        mRoot(x);

        access(y);

        splay(y);

        fa[ ch[y][0] ] = 0;

        ch[y][0] = 0;

        update(y);

    }



    inline void modify(int x,int y,int c){

        if(!jud(x,y)){

            puts("-1");

            return;

        }

        mRoot(x);

        access(y);

        splay(y);

        modify(y,c);

        clear(y);

    }



    inline int ask(int x,int y){

        if(!jud(x,y))

            return -1;

        mRoot(x);

        access(y);

        splay(y);

        return mx[y];

    }



}lct;



struct Edge{

    int y,next;

}edge[MAXN<<1];



int po[MAXN],tol;



inline void add(int x,int y){

    edge[++tol].y = y;

    edge[tol].next = po[x];

    po[x] = tol;

}



void dfs(int x,int pa){

    lct.fa[x] = pa;

    for(int i=po[x];i;i=edge[i].next)

        if(edge[i].y!=pa)

            dfs(edge[i].y,x);

}



int main(){



#ifndef ONLINE_JUDGE

    freopen("sum.in","r",stdin);

    //freopen("sum.out","w",stdout);

#endif



    int x,y,w,n,m,op;

    while(~RD(n)){

        lct.init();

        Clear(po);

        tol = 0;



        REP(i,2,n){

            Int(x);Int(y);

            add(x,y);

            add(y,x);

        }



        dfs(1,0);



        rep1(i,n){

            RD(lct.val[i]);

            lct.mx[i] = lct.val[i];

        }

        RD(m);

        while(m--){

            Int(op);

            if(op==1){

                Int(x);Int(y);

                lct.link(x,y);

            }else if(op==2){

                Int(x);Int(y);

                lct.cut(x,y);

            }else if(op==3){

                Int(w);Int(x);Int(y);

                lct.modify(x,y,w);

            }else{

                Int(x);Int(y);

                printf("%d\n",lct.ask(x,y));

            }

        }

        puts("");

    }



    return 0;

}

  

 

你可能感兴趣的:(query)