Query on a tree SPOJ
阿新 • • 發佈:2018-12-16
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 2e4+100; int son[maxn], deep[maxn], father[maxn], num[maxn], top[maxn], p[maxn], fp[maxn], pos; int Treevalue[maxn]; int first[maxn], ntot; struct Node { int to, next, val; } edge[maxn]; struct NODE { int a, b, c; } input[maxn]; void init() { memset(first, -1, sizeof(first)); memset(son, -1, sizeof(son)); pos = ntot = 0; } void addedge(int s,int t,int val) { edge[ntot].to=t,edge[ntot].val=val; edge[ntot].next=first[s],first[s]=ntot++; } ///樹鏈剖分 void dfs(int x, int pre, int de) { deep[x] = de; father[x] = pre; num[x] = 1; for(int i = first[x]; i != -1; i = edge[i].next) { int to = edge[i].to; if(to != pre) { Treevalue[to] = edge[i].val; dfs(to, x, de + 1); num[x] += num[to]; if(son[x] == -1 || num[to] > num[son[x]]) son[x] = to; } } return ; } void getlist(int x, int tp) { top[x] = tp; p[x] = pos++; fp[p[x]] = x; if(son[x] != -1) getlist(son[x], tp); else return ; for(int i = first[x]; i != -1; i = edge[i].next) { int to = edge[i].to; if(to != father[x] && to != son[x]) getlist(to, to); } } struct TreeNode { int l, r, max; } tree[maxn * 3]; void push_up(int i) { tree[i].max = max(tree[i << 1].max, tree[i << 1 | 1].max); } void build(int i,int l,int r) { tree[i].l=l,tree[i].r=r,tree[i].max=0; if(l==r) { tree[i].max=Treevalue[fp[l]]; return ; } int mid=(l+r)>>1; build(i<<1,l,mid); build(i<<1|1,mid+1,r); push_up(i); } int Query(int rt, int L, int R) { if(tree[rt].l >= L && tree[rt].r <= R) return tree[rt].max; int m = (tree[rt].l + tree[rt].r) >> 1; int ans = 0; if(L <= m) ans = max(ans, Query(rt << 1, L, R)); if(m < R) ans = max(ans, Query(rt << 1 | 1, L, R)); return ans; } void update(int i,int k,int val)//插點 { if(tree[i].l == k && tree[i].r == k) { tree[i].max=val; return ; } int mid=(tree[i].l+tree[i].r)>>1; if(k>mid) update(i<<1|1,k,val); else update(i<<1,k,val); push_up(i); } int getmax(int a, int b) { int res = 0; int f1 = top[a], f2 = top[b]; while(f1 != f2) { if(deep[f1] < deep[f2]) { swap(f1, f2); swap(a, b); } res = max(res, Query(1, p[f1], p[a])); a = father[f1]; f1 = top[a]; } if(a == b) return res; if(deep[a] > deep[b]) swap(a, b); return max(res, Query(1, p[son[a]], p[b])); } int main() { //freopen("in.txt", "r", stdin); int ncase, n; cin >> ncase; while(ncase--) { init(); cin >> n; for(int i = 1; i <= n - 1; i++) { scanf("%d%d%d",&input[i].a,&input[i].b,&input[i].c); addedge(input[i].a,input[i].b,input[i].c); addedge(input[i].b,input[i].a,input[i].c); } dfs(1, 0, 0); getlist(1,1); build(1, 1, n -1 ); while(1) { char op[10]; scanf("%s", op); if(op[0] == 'D') break; if(op[0] == 'C') { int a, b; scanf("%d%d", &a, &b); int aa = input[a].a, bb = input[a].b; if(deep[aa] < deep[bb]) swap(aa, bb); update(1, p[aa], b); } else { int a, b; scanf("%d%d", &a, &b); printf("%d\n", getmax(a, b)); } } } return 0; }