hdu 4010 LCT

題意很裸,調了好久,,最後發現push_up寫錯了,, splay功底還是不夠, 再刷一波splay...

#include <bits/stdc++.h>
using namespace std;
int n,m;
const int MAXN = 310010;
const int INF = 0x3f3f3f3f;
struct Node *null;
struct Node{
    Node * fa, *ch[2];
    int val, MAX;
    int rev, add;
    inline void clear(){
        val = 0;
        MAX = -INF;
        rev = add = 0;
        fa = ch[0] = ch[1] = null;
    }
    inline void push_up(){
        MAX = max(val, max(ch[0]->MAX, ch[1]->MAX));
    }
    inline void update_add(int w){
        if(this == null) return;
        val += w;
        add += w;
        MAX += w;
    }
    inline void push_down(){
        if(add){
            ch[0]->update_add(add);
            ch[1]->update_add(add);
            add = 0;
        }
        if(rev){
            ch[0]->flip();
            ch[1]->flip();
            rev = 0;
        }
    }
    inline bool d(){
        return fa->ch[1] == this;
    }
    inline void setc(Node *p, int d){
        ch[d] = p;
        p->fa = this;
    }
    inline bool isroot(){
        return fa==null||fa->ch[0]!=this&&fa->ch[1]!=this;
    }
    inline void rot(){
        Node *f = fa, *ff = fa->fa;
        bool c = d(), cc = fa->d();
        f->setc(ch[!c], c);
        this->setc(f, !c);
        if(ff->ch[cc] == f) ff->setc(this, cc);
        else this->fa = ff;
        f->push_up();
    }
    inline void go(){
        if(!isroot()) fa->go();
        push_down();
    }
    inline Node *splay(){
        go();
        while(!isroot()){
            rot();
        }
        push_up();
        return this;
    }
    inline Node *access(){
        for(Node *q=this,*p=null; q!=null; p=q,q=q->fa){
            q->splay()->setc(p, 1);
            q->push_up();
        }
        return splay();
    }
    inline void flip(){
        if(this == null) return;
        swap(ch[0], ch[1]);
        rev ^= 1;
    }
    inline void make_root(){
        access()->flip();
    }
    inline Node *find_root(){
        Node *x;
        for(x=access();x->push_down(),x->ch[0]!=null;x = x->ch[0]);
        return x;
    }
    inline void cut(){
        access();
        ch[0]->fa = null;
        ch[0] = null;
        push_up();
    }
    inline void cut(Node *x){
            x->make_root();
            cut();
    }
    inline void link(Node *x){
        make_root();
        fa = x;
    }
};
Node poor[MAXN];
Node *tail;
Node *node[MAXN];
void init(int n){
    tail = poor;
    null = tail++;
    null->clear();
    for(int i=1; i<=n; i++){
        node[i] = tail++;
        node[i]->clear();
    }
}
struct Edge{
    int to,next;
}edge[MAXN*2];
int tot,head[MAXN];
void add_edge(int u, int v){
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}
void dfs(int u, int pre){
    for(int i=head[u]; ~i; i=edge[i].next){
        int v = edge[i].to;
        if(v == pre) continue;
        dfs(v, u);
        node[v]->fa = node[u];
    }
}
void ADD(Node *x, Node *y, int w){
    x->access();
    for(x=null; y!=null; x=y,y=y->fa){
        y->splay();
        if(y->fa == null){
            y->ch[1]->update_add(w);
            x->update_add(w);
            y->val += w;
            y->push_up();
            return;
        }
        y->setc(x, 1);
        y->push_up();
    }
}
int ask(Node *x, Node *y){
    x->access();
    for(x=null;y!=null;x=y,y=y->fa){
        y->splay();
        if(y->fa == null){
        return max(y->val, max(y->ch[1]->MAX, x->MAX));
        }
        y->setc(x, 1);
        y->push_up();
    }
}
int main(){
    while(cin>>n){
        tot = 0;memset(head, -1, sizeof(head));
        for(int i=1; i<n; i++){
            int u,v,w;
            scanf("%d %d", &u, &v);
            add_edge(u, v);
            add_edge(v, u);
        }
        init(n);
        dfs(1, 1);
        for(int i=1; i<=n;i ++){
            int t;
            scanf("%d", &t);
            node[i]->val = t;
        }
        cin>>m;
        while(m--){
            int cmd, x, y,z;
            scanf("%d", &cmd);
            if(cmd == 1){
                scanf("%d %d",&x, &y);
                if(node[x]->find_root() == node[y]->find_root())
                {
                    cout<<-1<<endl;
                    continue;
                }
                node[x]->link(node[y]); 
            }
            else if(cmd == 2){
                scanf("%d %d",&x, &y);
                if(x==y||node[x]->find_root() != node[y]->find_root())
                {
                    cout<<-1<<endl;
                    continue;
                }
                node[y]->cut(node[x]);
            }
            else if(cmd == 3){
                scanf("%d %d %d", &x, &y, &z); 
                if(node[y]->find_root() != node[z]->find_root())
                {
                    cout<<-1<<endl;
                    continue;
                }
                ADD(node[y], node[z], x); 
            }
            else {
                scanf("%d %d", &x, &y);
                if(node[x]->find_root() != node[y]->find_root())
                {
                    cout<<-1<<endl;
                    continue;
                }
                printf("%d\n", ask(node[x], node[y]));
            }
        }
cout<<endl;
    }
    return 0;
}


發佈了58 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章