hdu 4010 Lct动态链接树

#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include <cstdio>
#include <memory>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <cassert>
#include <string>
#include <ctime>
#include <map>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <set>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define req(i,a,b) for(int i=a;i>=b;i--)
#define rp(i,a) for(int i=head[a];i+1;i=edge[i].next)
#define cl(a,b) memset(a,b,sizeof a);
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mod 10007
const int inf = ~0u >> 2;
const ll INF = (1LL << 62) - 1;
double eps = 1e-12;
const int N = 300005 + 5;
const int M = 300005;


int n, m, d;

class Lct {
public:
    Lct() {}
    ~Lct() {}
    struct Node {
        int value, size, add, reverse, mx;
        Node *parent, *child[2];
    }_nil, *node[N];
public:
    void Init() {
        nil = new Node;
        nil->child[0] = nil->child[1] = nil;
        nil->size = 0;
        nil->parent = nil;
        nil->mx = -(inf << 1) - 2;
        nil->add = 0;
        nil->value = -(inf << 1) - 2;
        nil->reverse = 0;
        Root = nil;
        //nil->
        //Insert(-(inf<<1)-2);
        //Insert((inf<<1)+1);
        //Insert(0);
        //Insert(n + 1);
    }
    bool IsRoot(Node *x) {
        if (x == nil)
            return true;
        if (x->parent->child[0] == x || x->parent->child[1] == x)
            return false;
        return true;
    }
    void update(Node *x) {
        /*if (x == nil)
            return;*/
        x->mx = max(x->value, max(x->child[0]->mx, x->child[1]->mx));
        //x->size = x->child[0]->size + x->child[1]->size + 1;
    }
    void down(Node *x) {
        if (x == nil)return;
        if (x->reverse) {
            if (x->child[0] != nil) {
                x->child[0]->reverse ^= 1;
            }
            if (x->child[1] != nil) {
                x->child[1]->reverse ^= 1;
            }
            swap(x->child[0], x->child[1]);
            x->reverse = 0;
        }
        if (x->add) {
            if (x->child[0] != nil) {
                x->child[0]->value += x->add;
                x->child[0]->mx += x->add;
                x->child[0]->add += x->add;
            }
            if (x->child[1] != nil) {
                x->child[1]->value += x->add;
                x->child[1]->mx += x->add;
                x->child[1]->add += x->add;
            }
            x->add = 0;
        }
    }
    void Rotate(Node *x, int dir) {
        if (IsRoot(x))return;
        Node * p = x->parent;
        if (p->parent->child[0] == p)
        {
            p->parent->child[0] = x;
        }
        else if (p->parent->child[1] == p) {
            p->parent->child[1] = x;
        }
        x->parent = p->parent;
        p->child[dir ^ 1] = x->child[dir];
        p->child[dir ^ 1]->parent = p;
        x->child[dir] = p;
        p->parent = x;
        update(p);
        update(x);
        /*if (Root == p) {
        Root = x;
        }*/
    }
    void Splay(Node *x) {
        static Node *sta[N];
        int top = 0;
        sta[top++] = x;
        for (Node *y = x; !IsRoot(y); y = y->parent)
            sta[top++] = y->parent;
        while (top)down(sta[--top]);
        while (!IsRoot(x)) {
            if (IsRoot(x->parent)) {
                if (x->parent->child[0] == x) {
                    Rotate(x, 1);
                }
                else {
                    Rotate(x, 0);
                }
            }
            else if (x->parent->parent->child[0] == x->parent) {
                if (x->parent->child[0] == x) {
                    Rotate(x->parent, 1);
                    Rotate(x, 1);
                }
                else {
                    Rotate(x, 0);
                    Rotate(x, 1);
                }
            }
            else {
                if (x->parent->child[1] == x) {
                    Rotate(x->parent, 0);
                    Rotate(x, 0);
                }
                else {
                    Rotate(x, 1);
                    Rotate(x, 0);
                }
            }
            update(x);
        }
    }
    Node *NewNode(Node *x, int val) {
        x = new Node;
        x->parent = nil;
        x->value = val;
        x->size = 1;
        x->add = 0;
        x->mx = val;
        x->reverse = 0;
        x->child[0] = x->child[1] = nil;
        return x;
    }
    void dfs(Node *u) {
        if (u->child[0] != nil)
            dfs(u->child[0]);
        printf(" %d", u->value);
        if (u->child[1] != nil)
            dfs(u->child[1]);
    }
    //void Insert(int u,int val){
    //  if (Root == nil) {
    //      Root = NewNode(nil, val);
    //      return;
    //  }
    //  Node *x=Root;
    //  while (x->child[val>=x->value]!=nil) {
    //      x = x->child[val>=x->value];
    //  }
    //  Node *t = NewNode(x,val);
    //  node[u] = t;
    //  x->child[val >= x->value] = t;
    //  update(x);
    //  Splay(t, nil);
    ///*    printf("dfs:");
    //  dfs(Root);
    //  printf("\n");*/
    //}
    //void Remove(int val) {
    //  int rnk = FindValRank(val);
    //  FindRankTo(rnk - 1, nil);
    //  FindRankTo(rnk + 1, Root);
    //  Root->child[1]->child[0] = nil;
    //  update(Root->child[1]);
    //  update(Root);
    //}
    //int FindValRank(int val) {
    //  Node *x = Root;
    //  int sum = 0;
    //  while (x->child[val >= x->value]!=nil) {
    //      if (x->value == val)
    //          return sum + 1 + x->child[0]->size;
    //      if (val >= x->value) {
    //          sum += x->child[0]->size+1;
    //      }
    //      x = x->child[val >= x->value];
    //  }
    //  return sum+1+x->child[0]->size;
    //}
    //void FindRankTo(int rnk, Node *y) {
    //  Node *x = Root;
    //  while (x!=nil) {
    //      if (rnk == x->child[0]->size+1)
    //      {
    //          Splay(x, y);
    //          return;
    //      }
    //      if (rnk > x->child[0]->size) {
    //          rnk -= x->child[0]->size + 1;
    //          x = x->child[1];
    //      }
    //      else
    //          x = x->child[0];
    //  }
    //}
    //int FindRoot(int x) {

    //}
    /*int FindRankVal(int k) {
    FindRankTo(k, nil);
    return Root->value;
    }*/
    Node *Access(Node *x) {
        Node *y = x;
        x = nil;
        while (y != nil) {
            Splay(y);
            //y->child[1]->parent = y;
            y->child[1] = x;
            x->parent = y;
            update(y);
            x = y;
            y = y->parent;
        }
        return x;
    }
    //Node *FindRoot(Node *x) {
    //  Access(x);
    //  Splay(x);
    //  while (x->child[0] != nil)x = x->child[0];
    //  Splay(x);
    //  return x;
    //}
    void Cut(Node *x) {
        //ChangeRoot(x->parent);
        /*Access(x);
        Splay(x);
        x->reverse ^= 1;*/
        ChangeRoot(x);
        x->child[0]->parent = nil;
        x->child[0] = nil;
        update(x);
    }
    void Link(Node *x, Node *y) {
        //printf("%d %d#\n", x->value, y->value);
        /*Access(x);
        Splay(x);
        x->reverse ^= 1;*/
        ChangeRoot(x);
        x->parent = y;
        //Access(x);
        //
    }
    void ChangeRoot(Node *x) {
        Access(x);
        Splay(x);
        x->reverse ^= 1;
    }
    void AddVal(Node *x, Node *y, int val) {
        ChangeRoot(y);
        ChangeRoot(x);
        //Node *u = Access(x);
        //Node *u = BecomeRoot(x);
        /*Cut(y->child[1]);
        while (y->child[0] != x)y = y->child[0];
        Cut(x->child[0]);*/
        //Access(x);
        x->value += val;
        x->add += val;
        x->mx += val;
    }
    int QueryMaxVal(Node *x, Node *y) {
        ChangeRoot(y);
        ChangeRoot(x);
        //Node *u = Access(x);
        //BecomeRoot(x);
        return x->mx;
        /*Cut(y->child[1]);
        while(y->child[0])*/
    }
    bool IsSameTree(Node *u, Node *v) {
        while (u->parent != nil)u = u->parent;
        while (v->parent != nil)v = v->parent;
        return u == v;
    }
public:
    int w[N];
    Node *Root, *nil;
};
struct Seg {
    int l, r, k, index;
    bool operator < (const Seg & rhs)const {
        return r < rhs.r;
    }
}seg[M];
Lct lct;
//SplayTree spt;
int ans[M];
void printErr() {
    printf("-1\n");
}
int nd1[N], nd2[N];
int main() {
    int n;
    while (scanf("%d",&n)!=-1) {
        lct.Init();
        for (int i = 1; i < n; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            //g[u].push_back(v);
            nd1[i] = u;
            nd2[i] = v;
        }
        for (int i = 1; i <= n; i++) {
            scanf("%d", &lct.w[i]);
            lct.node[i] = lct.NewNode(lct.node[i], lct.w[i]);
        }
        for (int i = 1; i < n; i++)
            lct.Link(lct.node[nd1[i]], lct.node[nd2[i]]);
        /*for (int i = 1; i <= n; i++)
            for (int j = 0; j < g[i].size(); j++)
                lct.Link(lct.node[i], lct.node[g[i][j]]);*/
                //for (int i = 1; i <= n; i++) {
                //  if (lct.IsRoot(lct.node[i])) {
                //      printf("Root :%d", i);
                //      lct.dfs(lct.node[i]);
                //      printf("\n");
                //  }
                //}
        scanf("%d", &m);
        while (m--) {
            int op;
            scanf("%d", &op);
            if (op == 1) {
                int x, y;
                scanf("%d%d", &x, &y);
                if (lct.IsSameTree(lct.node[x], lct.node[y])) {
                    printErr();
                    continue;
                }
                lct.Link(lct.node[x], lct.node[y]);
            }
            if (op == 2) {
                int x, y;
                scanf("%d%d", &x, &y);
                if (x==y||!lct.IsSameTree(lct.node[x], lct.node[y])) {
                    printErr();
                    continue;
                }
                lct.ChangeRoot(lct.node[x]);
                lct.Cut(lct.node[y]);
            }
            if (op == 3) {
                int w, x, y;
                scanf("%d%d%d", &w, &x, &y);
                if (!lct.IsSameTree(lct.node[x], lct.node[y])) {
                    printErr();
                    continue;
                }
                lct.AddVal(lct.node[x], lct.node[y], w);
            }
            if (op == 4) {
                int x, y;
                scanf("%d%d", &x, &y);
                if (!lct.IsSameTree(lct.node[x], lct.node[y])) {
                    printErr();
                    continue;
                }
                printf("%d\n", lct.QueryMaxVal(lct.node[x], lct.node[y]));
            }
        }
        printf("\n");
    }
    return 0;
}

转载于:https://www.cnblogs.com/HaibaraAi/p/6368685.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值