SPOJ 375 (树链剖分 - 边权剖分 - 修改单边权)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/I
给你一棵有边权的树,有两个操作:一个操作是输出l到r点之间的最大的边权,另一个操作是修改某条边的权值。
这题是树链剖分的简单模版题,代码如下:
1 //修改单边权 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 const int MAXN = 1e4 + 10; 7 struct data { 8 int next , to , cost; 9 }edge[MAXN << 1]; 10 int head[MAXN] , top[MAXN] , id[MAXN] , par[MAXN] , dep[MAXN] , size[MAXN] , son[MAXN]; 11 int cnt , tot , v[MAXN] , u[MAXN] , cost[MAXN]; 12 13 void init() { 14 cnt = tot = 0; 15 memset(head , -1 , sizeof(head)); 16 } 17 18 inline void add(int u , int v , int cost) { 19 edge[cnt].next = head[u]; 20 edge[cnt].to = v; 21 edge[cnt].cost = cost; 22 head[u] = cnt++; 23 } 24 25 void dfs_1(int u , int p , int d) { 26 dep[u] = d , par[u] = p , size[u] = 1 , son[u] = u; 27 for(int i = head[u] ; ~i ; i = edge[i].next) { 28 int v = edge[i].to; 29 if(v == p) 30 continue; 31 dfs_1(v , u , d + 1); 32 if(size[son[u]] < size[v]) 33 son[u] = v; 34 size[u] += size[v]; 35 } 36 } 37 38 void dfs_2(int u , int p , int t) { 39 top[u] = t , id[u] = ++tot; 40 if(son[u] != u) 41 dfs_2(son[u] , u , t); 42 for(int i = head[u] ; ~i ; i = edge[i].next) { 43 int v = edge[i].to; 44 if(v == p || v == son[u]) 45 continue; 46 dfs_2(v , u , v); 47 } 48 } 49 50 struct segtree { 51 int l , r , Max; 52 }T[MAXN << 2]; 53 54 void build(int p , int l , int r) { 55 int mid = (l + r) >> 1; 56 T[p].l = l , T[p].r = r; 57 if(l == r) 58 return ; 59 build(p << 1 , l , mid); 60 build((p << 1)|1 , mid + 1 , r); 61 } 62 63 void updata(int p , int pos , int num) { 64 int mid = (T[p].l + T[p].r) >> 1; 65 if(T[p].l == T[p].r) { 66 T[p].Max = num; 67 return ; 68 } 69 if(pos <= mid) 70 updata(p << 1 , pos , num); 71 else 72 updata((p << 1)|1 , pos , num); 73 T[p].Max = max(T[p << 1].Max , T[(p << 1)|1].Max); 74 } 75 76 int query(int p , int l , int r) { 77 int mid = (T[p].l + T[p].r) >> 1; 78 if(l == T[p].l && T[p].r == r) 79 return T[p].Max; 80 if(r <= mid) 81 return query(p << 1 , l , r); 82 else if(l > mid) 83 return query((p << 1)|1 , l , r); 84 else 85 return max(query(p << 1 , l , mid) , query((p << 1)|1 , mid + 1 , r)); 86 } 87 88 int Find(int l , int r) { 89 int pl = top[l] , pr = top[r] , Max = 0; 90 while(pl != pr) { 91 if(dep[pl] > dep[pr]) { 92 Max = max(Max , query(1 , id[pl] , id[l])); 93 l = par[pl]; 94 pl = top[l]; 95 } 96 else { 97 Max = max(Max , query(1 , id[pr] , id[r])); 98 r = par[pr]; 99 pr = top[r]; 100 } 101 } 102 if(r == l) 103 return Max; 104 else if(dep[r] > dep[l]) 105 return max(Max , query(1 , id[son[l]] , id[r])); 106 else 107 return max(Max , query(1 , id[son[r]] , id[l])); 108 } 109 110 int main() 111 { 112 int t , n , l , r; 113 scanf("%d" , &t); 114 while(t--) { 115 scanf("%d" , &n); 116 init(); 117 for(int i = 1 ; i < n ; ++i) { 118 scanf("%d %d %d" , u + i , v + i , cost + i); 119 add(u[i] , v[i] , cost[i]); 120 add(v[i] , u[i] , cost[i]); 121 } 122 dfs_1(1 , 1 , 0); 123 dfs_2(1 , 1 , 1); 124 build(1 , 1 , tot); 125 for(int i = 1 ; i < n ; ++i) { 126 if(dep[u[i]] > dep[v[i]]) 127 swap(u[i] , v[i]); 128 updata(1 , id[v[i]] , cost[i]); 129 } 130 char q[10]; 131 while(scanf("%s" , q) && q[0] != 'D') { 132 scanf("%d %d" , &l , &r); 133 if(q[0] == 'C') { 134 updata(1 , id[v[l]] , r); 135 } 136 else { 137 printf("%d\n" , Find(l , r)); 138 } 139 } 140 } 141 return 0; 142 }