标签:
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.
For each test case:
There is one blank line between successive tests.
For each "QUERY" operation, write one integer representing its result.
Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3
解题:树链剖分
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 10100; 4 struct arc{ 5 int to,next; 6 arc(int x = 0,int y = -1){ 7 to = x; 8 next = y; 9 } 10 }e[30000]; 11 struct node{ 12 int lt,rt,val; 13 }tree[maxn<<2]; 14 int head[maxn],fa[maxn],dep[maxn],son[maxn],tot; 15 int siz[maxn],top[maxn],tid[maxn],label; 16 void add(int u,int v){ 17 e[tot] = arc(v,head[u]); 18 head[u] = tot++; 19 } 20 void Find_heavy_edge(int u,int father,int depth){ 21 siz[u] = 1; 22 dep[u] = depth; 23 fa[u] = father; 24 son[u] = -1; 25 for(int i = head[u]; ~i; i = e[i].next){ 26 if(e[i].to == father) continue; 27 Find_heavy_edge(e[i].to,u,depth + 1); 28 siz[u] += siz[e[i].to]; 29 if(son[u] == -1 || siz[e[i].to] > siz[son[u]]) 30 son[u] = e[i].to; 31 } 32 } 33 void connect_heavy_edge(int u,int ancestor){ 34 tid[u] = label++; 35 top[u] = ancestor; 36 for(int i = head[u]; ~i; i = e[i].next){ 37 if(e[i].to == fa[u]) continue; 38 if(e[i].to == son[u]) connect_heavy_edge(e[i].to,ancestor); 39 else connect_heavy_edge(e[i].to,e[i].to); 40 } 41 } 42 inline void pushup(int v){ 43 tree[v].val = max(tree[v<<1].val,tree[v<<1|1].val); 44 } 45 void build(int lt,int rt,int v){ 46 tree[v].lt = lt; 47 tree[v].rt = rt; 48 tree[v].val = 0; 49 if(lt == rt) return; 50 int mid = (lt + rt)>>1; 51 build(lt,mid,v<<1); 52 build(mid+1,rt,v<<1|1); 53 } 54 void update(int pos,int val,int v){ 55 if(tree[v].lt == tree[v].rt){ 56 tree[v].val = val; 57 return; 58 } 59 if(pos <= tree[v<<1].rt) update(pos,val,v<<1); 60 if(pos >= tree[v<<1|1].lt) update(pos,val,v<<1|1); 61 pushup(v); 62 } 63 int query(int lt,int rt,int v){ 64 int ret = 0; 65 if(lt <= tree[v].lt && rt >= tree[v].rt) return tree[v].val; 66 if(lt <= tree[v<<1].rt) ret = query(lt,rt,v<<1); 67 if(rt >= tree[v<<1|1].lt) ret = max(ret,query(lt,rt,v<<1|1)); 68 return ret; 69 } 70 int Find(int u,int v){ 71 int f1 = top[u],f2 = top[v],tmp = 0; 72 while(f1 != f2){ 73 if(dep[f1] < dep[f2]){ 74 swap(f1,f2); 75 swap(u,v); 76 } 77 tmp = max(tmp,query(tid[f1],tid[u],1)); 78 u = fa[f1]; 79 f1 = top[u]; 80 } 81 if(u == v) return tmp; 82 if(dep[u] > dep[v]) swap(u,v); 83 return max(tmp,query(tid[son[u]],tid[v],1)); 84 } 85 int ac[maxn][3]; 86 int main(){ 87 int kase,n,u,v; 88 char op[10]; 89 scanf("%d",&kase); 90 while(kase--){ 91 memset(head,-1,sizeof head); 92 scanf("%d",&n); 93 for(int i = tot = 0; i < n-1; ++i){ 94 scanf("%d%d%d",&ac[i][0],&ac[i][1],&ac[i][2]); 95 add(ac[i][0],ac[i][1]); 96 add(ac[i][1],ac[i][0]); 97 } 98 label = 0; 99 Find_heavy_edge(1,0,0); 100 connect_heavy_edge(1,1); 101 build(0,label-1,1); 102 for(int i = 0; i < n-1; ++i){ 103 if(dep[ac[i][0]] > dep[ac[i][1]]) 104 swap(ac[i][0],ac[i][1]); 105 update(tid[ac[i][1]],ac[i][2],1); 106 } 107 while(~scanf("%s",op)){ 108 if(op[0] == ‘D‘) break; 109 scanf("%d%d",&u,&v); 110 if(op[0] == ‘Q‘) printf("%d\n",Find(u,v)); 111 else update(tid[ac[u-1][1]],v,1); 112 } 113 } 114 return 0; 115 }
标签:
原文地址:http://www.cnblogs.com/crackpotisback/p/4822059.html