HDU4010 LCT

来源:互联网 发布:廊坊盛秋网络 编辑:程序博客网 时间:2024/05/10 14:31
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>#include <set>#include <map>#include <stack>#include <queue>#include <vector>using namespace std;#define REP(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; ++i)#define DREP(i, a, b) for (int i = (a), _begin_ = (b); i >= _begin_; --i)#define debug(...) fprintf(stderr, __VA_ARGS__)#define mp make_pair#define x first#define y second#define pb push_back#define SZ(x) (int((x).size()))#define ALL(x) (x).begin(), (x).end()template<typename T> inline bool chkmin(T &a, const T &b){ return a > b ? a = b, 1 : 0; }template<typename T> inline bool chkmax(T &a, const T &b){ return a < b ? a = b, 1 : 0; }typedef long long LL;const int dmax = 300100, oo = 0x3f3f3f3f;int n, m;struct node{    node *f, *ch[2];    int val, max, rev, add;}c[dmax], *cur, *Null;#define L ch[0]#define R ch[1]node *new_node(int k){    cur->val = cur->max = k;    cur->rev = cur->add = 0;    cur->f = cur->L = cur->R = Null;    return cur++;}void init(){    Null = c;    Null->f = Null->L = Null->R = Null;    Null->val = Null->max = -oo;    Null->rev = Null->add = 0;    cur = c + 1;}struct lct{    inline bool is_root(node *t) { return t == Null || t->f->L != t && t->f->R != t; }    inline void push_up(node *t) { t->max = max(t->val, max(t->L->max, t->R->max)); }    inline void push_down(node *t)    {        if (t->rev)        {            if (t->L != Null) t->L->rev ^= 1;            if (t->R != Null) t->R->rev ^= 1;            t->rev = 0;            swap(t->L, t->R);        }        if (t->add)        {            if (t->L != Null) t->L->val += t->add, t->L->max += t->add, t->L->add += t->add;            if (t->R != Null) t->R->val += t->add, t->R->max += t->add, t->R->add += t->add;            t->add = 0;        }    }    inline void rotate(node *x)    {        if (is_root(x)) return;        node *y = x->f;        int k = x == y->R;        x->f = y->f;        y->ch[k] = x->ch[!k];        if (x->ch[!k] != Null) x->ch[!k]->f = y;        if (!is_root(y))        {            if (y == y->f->L)                y->f->L = x;            else y->f->R = x;        }        x->ch[!k] = y;        y->f = x;        push_up(y);    }    void splay(node *x)    {        static node *S[dmax];        int top = 1;        S[0] = x;        for (node *Cur = x; !is_root(Cur); Cur = Cur->f)            S[top++] = Cur->f;        while (top > 0) push_down(S[--top]);        while (!is_root(x))        {            node *y = x->f;            if (!is_root(y))                rotate(x);            else{                if (x == y->f->L->L || x == y->f->R->R)                    rotate(y);                else rotate(x);                rotate(x);            }        }        push_up(x);    }    node *access(node *x)    {        node *y = Null;        while (x != Null)        {            splay(x);            x->R = y;            y->f = x;            push_up(x);            y = x;            x = x->f;        }        return y;    }        inline void change_root(node *x) { access(x)->rev ^= 1; splay(x); }    inline void link(node *x, node *y)    {        change_root(x);        x->f = y;        access(x);    }    inline void cut(node *x)    {        access(x);        splay(x);        x->L = x->L->f = Null;        push_up(x);    }    node *get_root(node *x)    {        access(x);        splay(x);        while (x->L != Null) x = x->L;        splay(x);        return x;    }    bool p(node *x, node *y)    {        while (x->f != Null) x = x->f;        while (y->f != Null) y = y->f;        return x == y;    }}t;int eu[dmax], ev[dmax];int main(){#ifndef ONLINE_JUDGE    freopen("input.txt", "r", stdin);    freopen("output.txt", "w", stdout);#endif    while (scanf("%d", &n) != EOF)    {        init();        REP(i, 1, n - 1)            scanf("%d%d", &eu[i], &ev[i]);        REP(i, 1, n)        {            int k;            scanf("%d", &k);            new_node(k);        }        REP(i, 1, n - 1)            t.link(c + eu[i], c + ev[i]);        scanf("%d", &m);        REP(i, 1, m)        {            int T, x, y;            scanf("%d", &T);            if (T == 1)            {                scanf("%d%d", &x, &y);                if (t.p(c + x, c + y))                {                    puts("-1");                    continue;                }                t.link(c + x, c + y);            } else if (T == 2) {                scanf("%d%d", &x, &y);                if (x == y || !t.p(c + x, c + y))                {                    puts("-1");                    continue;                }                t.change_root(c + x);                t.cut(c + y);            } else if (T == 3) {                int w;                scanf("%d%d%d", &w, &x, &y);                if (!t.p(c + x, c + y))                {                    puts("-1");                    continue;                }                t.change_root(c + x);                t.access(c + y);                node *q = t.get_root(c + y);                q->add += w;                q->max += w;                q->val += w;            } else {                scanf("%d%d", &x, &y);                if (!t.p(c + x, c + y))                {                    puts("-1");                    continue;                }                t.change_root(c + x);                t.access(c + y);                printf("%d\n", t.get_root(c + y)->max);            }        }        puts("");    }    return 0;}
0 0
原创粉丝点击