Query on a tree(LCT版)

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/C20190102/article/details/102510412

Article Directory

topic

Query on a tree

analysis

On the dynamic tree (LCT)

Code

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

int read(){
    int x=0;bool f=0;char c=getchar();
    while(c<'0'||c>'9') f|=c=='-',c=getchar();
    while(c>='0'&&c<='9') x=x*10+(c^48),c=getchar();
    return f?-x:x;
}

#define IL inline
#define LL long long
#define MAXN 50005
#define INF 0x7fffffff

struct Node{
    int Val,Max;
    Node *fa,*ch[2];
}*NIL,*ncnt,Sp[MAXN+5],*A[MAXN+5];

IL Node *NewNode(int val){
    Node *p=++ncnt;
    p->Val=p->Max=val;
    p->fa=p->ch[0]=p->ch[1]=NIL;
    return p;
}
IL bool Dir(Node *u){
    return u->fa->ch[1]==u;
}
IL bool isRoot(Node *u){
    return u->fa==NIL||(u->fa->ch[0]!=u&&u->fa->ch[1]!=u);
}
IL void SetChild(Node *u,Node *v,bool d){
    u->ch[d]=v;
    if(v!=NIL)
        v->fa=u;
}
IL void PushUp(Node *u){
    u->Max=max(u->Val,max(u->ch[0]->Max,u->ch[1]->Max));
}

IL void Rotate(Node *u){
    bool d=Dir(u);
    Node *y=u->fa;
    if(isRoot(y))
        u->fa=y->fa;
    else
        SetChild(y->fa,u,Dir(y));
    SetChild(y,u->ch[!d],d);
    SetChild(u,y,!d);
    PushUp(y);
}
void Splay(Node *u){
    while(!isRoot(u)){
        Node *y=u->fa;
        if(isRoot(y))
            Rotate(u);
        else{
            if(Dir(u)==Dir(y))
                Rotate(y);
            else
                Rotate(u);
            Rotate(u);
        }
    }
    PushUp(u);
}
Node *Access(Node *u){
    Node *r=NIL;
    while(u!=NIL){
        Splay(u);
        SetChild(u,r,1);
        PushUp(u);
        r=u,u=u->fa;
    }
    return r;
}
Node *GetRoot(Node *u){
    Access(u),Splay(u);
    Node *r=u;
    while(r->ch[0]!=NIL)
        r=r->ch[0];
    Splay(r);
    return r;
}
IL void MakeRoot(Node *u){
    Access(u);
    Splay(u);
}
IL void Link(Node *u,Node *v){
    MakeRoot(u);
    u->fa=v;
}
IL void Cut(Node *u,Node *v){
    MakeRoot(u);
    Access(v);
    Splay(v);
    u->fa=NIL;
    v->ch[0]=NIL;
}

int ID[MAXN+5];
struct Edge{
    int v,w,id;
};
vector<Edge> G[MAXN+5];
void Init(){
    NIL=ncnt=&Sp[0];
    NIL->fa=NIL->ch[0]=NIL->ch[1]=NIL;
    NIL->Val=NIL->Max=-INF;
}
void Modify(int e,int val){
    Node *p=A[ID[e]];
    Access(p);
    p->Val=val;
    PushUp(p);
}
int Query(int u,int v){
    Access(A[u]);
    Node *y=Access(A[v]);
    Splay(A[u]);
    int ret=y->ch[1]->Max;
    if(y!=A[u])
        ret=max(ret,A[u]->Max);
    return ret;
}
void dfs(int u,int fa){
    for(int i=0;i<int(G[u].size());i++){
        int v=G[u][i].v,w=G[u][i].w,id=G[u][i].id;
        if(v!=fa){
            ID[id]=v;
            A[v]=NewNode(w);
            A[v]->fa=A[u];
            dfs(v,u);
        }
    }
}

int main(){
    int T=read();
    while(T--){
        Init();
        int N=read();
        for(int i=1;i<=N;i++)
            G[i].clear();
        for(int i=1;i<=N-1;i++){
            int u=read(),v=read(),w=read();
            G[u].push_back((Edge){v,w,i});
            G[v].push_back((Edge){u,w,i});
        }
        A[1]=NewNode(-INF);
        dfs(1,-1);
        while(1){
            char opt[10];
            scanf("%s",opt);
            if(opt[0]=='D')
                break;
            int u=read(),v=read();
            if(opt[0]=='C')
                Modify(u,v);
            else
                printf("%d\n",Query(u,v));
        }
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/C20190102/article/details/102510412