hdu 4010 Query on The Trees (lct模板)

来源:互联网 发布:up up up网络用语 编辑:程序博客网 时间:2024/05/19 13:25
#include<iostream>#include<string>#include<cstring>#include<cstdio>#include<cmath>#include<queue>#include<set>#include<algorithm>using namespace std;#define LL long long#define eps 1e-8#define MP make_pair#define N 300020#define M 600020#pragma comment(linker, "/STACK:1024000000,1024000000")#define ls (i << 1)#define rs (ls | 1)#define md ((ll + rr) >> 1)#define lson ll, md, ls#define rson md + 1, rr, rs#define mod 258280327#define inf 0x3f3f3f3f#define ULL unsigned long longint readint() {    char c;    while((c = getchar()) && !(c >= '0' && c <= '9'));    int ret = c - '0';    while((c = getchar()) && c >= '0' && c <= '9')        ret = ret * 10 + c - '0';    return ret;}int fst[N], nxt[M], to[M], e;int tot, pre[N], ch[N][2], key[N];int add[N], rev[N], mx[N];bool rt[N];int n, m;void init() {memset(fst, -1, sizeof fst);memset(ch, 0, sizeof ch);memset(pre, 0, sizeof pre);memset(rev, 0, sizeof rev);memset(add, 0, sizeof add);memset(rt, 1, sizeof rt);e = 0;}void add_edge(int u, int v) {to[e] = v, nxt[e] = fst[u], fst[u] = e++;}void dfs(int u, int p) {pre[u] = p;for(int i = fst[u]; ~i; i = nxt[i]) {int v = to[i];if(v != p)dfs(v, u);}}bool judge(int u, int v) {while(pre[u]) u = pre[u];while(pre[v]) v = pre[v];return u == v;}void push_up(int x) {mx[x] = max(mx[ch[x][0]], mx[ch[x][1]]);mx[x] = max(mx[x], key[x]);}void update_add(int x, int val) {if(!x) return;key[x] += val;add[x] += val;mx[x] += val;}void update_rev(int x) {if(!x) return;swap(ch[x][0], ch[x][1]);rev[x] ^= 1;}void push_down(int x) {if(add[x]) {update_add(ch[x][0], add[x]);update_add(ch[x][1], add[x]);add[x] = 0;}if(rev[x]) {update_rev(ch[x][0]);update_rev(ch[x][1]);rev[x] = 0;}}void P(int x) {if(!rt[x]) P(pre[x]);push_down(x);}void rot(int x) {int y = pre[x], d = ch[y][1] == x;ch[y][d] = ch[x][!d];pre[ch[x][!d]] = y;pre[x] = pre[y];pre[y] = x;ch[x][!d] = y;if(rt[y])rt[y] = false, rt[x] = true;elsech[pre[x]][ch[pre[x]][1]==y] = x;push_up(y);}void splay(int x) {P(x);while(!rt[x]) {int f = pre[x], ff = pre[f];if(rt[f])rot(x);else if((ch[ff][1] == f) == (ch[f][1] == x))rot(f), rot(x);elserot(x), rot(x);}push_up(x);}// return the root of xint Access(int x) {int y = 0;for(; x; y = x, x = pre[x]) {splay(x);rt[ch[x][1]] = true;ch[x][1] = y;rt[y] = false;push_up(x);}return y;}void make_root(int u) {Access(u);splay(u);update_rev(u);}void link(int u, int v) {if(judge(u, v)) {puts("-1");return;}make_root(u);pre[u] = v;}void cut(int u, int v) {if(u == v || !judge(u, v)) {puts("-1");return;}make_root(u);splay(v);pre[ch[v][0]] = pre[v];pre[v] = 0;rt[ch[v][0]] = true;ch[v][0] = 0;push_up(v);}//调用后u是原来u和v的lca,v和ch[u][1]分别存着lca的2个儿子//(原来u和v所在的2颗子树)void lca(int &u, int &v) {Access(v), v = 0;for(splay(u); pre[u]; v = u, u = pre[u], splay(u)) {rt[ch[u][1]] = true;ch[u][1] = v;rt[v] = false;push_up(u);}}void update(int u, int v, int w) {if(!judge(u, v)) {puts("-1");return;}lca(u, v);update_add(ch[u][1], w);update_add(v, w);key[u] += w;push_up(u);}void query(int u, int v) {if(!judge(u, v)) {puts("-1");return;}lca(u, v);printf("%d\n", max(max(mx[ch[u][1]], mx[v]), key[u]));}int main() {while(scanf("%d", &n) != -1) {init();for(int i = 1; i < n; ++i) {int u, v;scanf("%d%d", &u, &v);add_edge(u, v);add_edge(v, u);}mx[0] = -inf;for(int i = 1; i <= n; ++i) {scanf("%d", &key[i]);mx[i] = key[i];}dfs(1, 0);scanf("%d", &m);while(m--) {int u, v, w, op;scanf("%d", &op);if(op == 3) scanf("%d", &w);scanf("%d%d", &u, &v);if(op == 1) {link(u, v);}if(op == 2) {cut(u, v);}if(op == 3) update(u, v, w);if(op == 4) query(u, v);}puts("");}return 0;}

0 0
原创粉丝点击