您的位置:首页 > 产品设计 > UI/UE

HDU 4010 Query on the tree LCT模板题

2016-08-04 13:59 441 查看
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x7fffffff;
const int maxn = 100000 + 10;

int n, m;
struct LinkCutTree {
bool rt[maxn];
int rev[maxn], add[maxn];
int Val[maxn], Max[maxn];
int fa[maxn], c[maxn][2];

void init(int *key) {
for(int i=0; i<=n; i++) {
rt[i] = true;
Val[i] = Max[i] = key[i];
rev[i] = add[i] = fa[i] = c[i][0] = c[i][1] = 0;
}Val[0] = Max[0] = -INF;
}
void Push_up(int u) {
Max[u] = Val[u];
if(c[u][0]) Max[u] = max(Max[u], Max[c[u][0]]);
if(c[u][1]) Max[u] = max(Max[u], Max[c[u][1]]);
}
void Push_down(int u) {
if(add[u]) {
if(c[u][0]) Max[c[u][0]] += add[u], Val[c[u][0]] += add[u], add[c[u][0]] += add[u];
if(c[u][1]) Max[c[u][1]] += add[u], Val[c[u][1]] += add[u], add[c[u][1]] += add[u];
add[u] = 0;
}if(rev[u]) {
rev[u] = 0;
if(c[u][0]) rev[c[u][0]] ^= 1;
if(c[u][1]) rev[c[u][1]] ^= 1;
swap(c[u][0], c[u][1]);
}
}
void rotate(int u) {
int v = fa[u], w = fa[v], t = c[v][1] == u;

c[v][t] = c[u][!t], fa[c[u][!t]] = v;
fa[u] = fa[v], fa[v] = u, c[u][!t] = v;

if(!rt[v]) c[w][c[w][1] == v] = u;
else rt[u] = 1, rt[v] = 0;
Push_up(v);
}
int stack[maxn];
void Splay(int u) {

int top = 1; stack[0] = u;
for(int cur = u; !rt[cur]; cur = fa[cur]) stack[top++] = fa[cur];
while(top) Push_down(stack[--top]);

while(!rt[u]) {
int v = fa[u], w = fa[v];
if(rt[v])
rotate(u);
else if((c[v][0] == u) == (c[w][0] == v))
rotate(v), rotate(u);
else rotate(u), rotate(u);
}
Push_up(u);
}
int access(int u) {
int v = 0;
while(u) {
Splay(u);
rt[c[u][1]] = 1, rt[v] = 0;
c[u][1] = v;
Push_up(u);
v = u;
u = fa[u];
}
return v;
}
void Change_root(int u) {
rev[access(u)] ^= 1;
Splay(u);
}
int Get_root(int u) {
access(u);
Splay(u);
while(c[u][0]) u = c[u][0];
Splay(u);
return u;
}
void link(int u, int v) {
Change_root(u);
fa[u] = v;
//rt[u] = false;
access(u);
}
void cut(int u) {
access(u);
Splay(u);
rt[c[u][0]] = true;
c[u][0] = fa[c[u][0]] = 0;
Push_up(u);
}
bool linked(int u, int v) {
while(fa[u]) u = fa[u];
while(fa[v]) v = fa[v];
return u == v;
}
}LCT;

int key[maxn], u[maxn], v[maxn];
int main() {
#ifndef ONLINE_JUDGE
freopen("data.txt", "r", stdin);
freopen("ans.txt", "w", stdout);
#endif
while(scanf("%d", &n) == 1) {
for(int i=1; i<n; i++) scanf("%d%d", &u[i], &v[i]);
for(int i=1; i<=n; i++) scanf("%d", &key[i]); LCT.init(key);
for(int i=1; i<n; i++) LCT.link(u[i], v[i]);

scanf("%d", &m);
while(m--) {
int cmd, x, y, z;
scanf("%d", &cmd);
if(cmd == 1) {
scanf("%d%d", &x, &y);
if(LCT.linked(x, y)) { puts("-1"); continue; }
LCT.link(x, y);
}else if(cmd == 2) {
scanf("%d%d", &x, &y);
if(x == y || !LCT.linked(x, y)) { puts("-1"); continue; }
LCT.Change_root(x); LCT.cut(y);
}else if(cmd == 3) {
scanf("%d%d%d", &z, &x, &y);
if(!LCT.linked(x, y)) { puts("-1"); continue; }
LCT.Change_root(x); LCT.access(y);
int r = LCT.Get_root(y);
LCT.add[r] += z; LCT.Max[r] += z; LCT.Val[r] += z;
}else {
scanf("%d%d", &x, &y);
if(!LCT.linked(x, y)) { puts("-1"); continue; }
LCT.Change_root(x); LCT.access(y);
int r = LCT.Get_root(y);

printf("%d\n", LCT.Max[r]);
}
}
cout << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LCT