SPOJ375 Query on a tree(树链剖分)
题意
给出一棵树,每条边都有权值,有两种操作:
- 把第p条边的权值改为x
- 询问x,y路径上的权值最大的边
code
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define lson l,m,rt<<1 5 #define rson m+1,r,rt<<1|1 6 7 using namespace std; 8 9 const int N = 100010; 10 struct Edge { 11 int to,nxt,w; 12 }e[200100]; 13 int head[N],tot,tn,n; 14 int deth[N],son[N],fa[N],siz[N],bel[N],pos[N]; 15 int mx[N<<2],a[N],b[N],c[N],data[N]; 16 17 void init() { 18 tot = tn = 0; 19 memset(head,0,sizeof(head)); 20 memset(son,0,sizeof(son)); 21 } 22 inline void add_edge(int u,int v,int w) { 23 e[++tot].to = v,e[tot].w = w,e[tot].nxt = head[u],head[u] = tot; 24 } 25 void dfs1(int u,int pa) { 26 siz[u] = 1; 27 for (int i=head[u]; i; i=e[i].nxt) { 28 int v = e[i].to; 29 if (v==pa) continue; 30 fa[v] = u; 31 deth[v] = deth[u] + 1; 32 dfs1(v,u); 33 siz[u] += siz[v]; 34 if (son[u]==0 || siz[v] > siz[son[u]]) son[u] = v; 35 } 36 } 37 void dfs2(int u,int top) { 38 pos[u] = ++tn; 39 bel[u] = top; 40 if (!son[u]) return ; 41 dfs2(son[u],top); 42 for (int i=head[u]; i; i=e[i].nxt) { 43 int v = e[i].to; 44 if (v != fa[u] && v != son[u]) dfs2(v,v); 45 } 46 } 47 void pushup(int rt) { 48 mx[rt] = max(mx[rt<<1],mx[rt<<1|1]); 49 } 50 void build(int l,int r,int rt) { 51 if (l==r) { 52 mx[rt] = data[l];return ; 53 } 54 int m = (l + r) >> 1; 55 build(lson); 56 build(rson); 57 pushup(rt); 58 } 59 void update(int l,int r,int rt,int p,int x) { 60 if (l==r) { 61 mx[rt] = x;return ; 62 } 63 int m = (l + r) >> 1; 64 if (p <= m) update(lson,p,x); 65 else update(rson,p,x); 66 pushup(rt); 67 } 68 int query(int l,int r,int rt,int L,int R) { 69 if (L <= l && r <= R) { 70 return mx[rt]; 71 } 72 int m = (l + r) >> 1; 73 int ret = -1e9; 74 if (L <= m) ret = max(ret,query(lson,L,R)); 75 if (R > m) ret = max(ret,query(rson,L,R)); 76 return ret; 77 } 78 void Change(int p,int x) { 79 if (deth[a[p]] > deth[b[p]]) update(2,n,1,pos[a[p]],x); 80 else update(2,n,1,pos[b[p]],x); 81 } 82 int Ask(int x,int y) { 83 int ans = -1e9; 84 while (bel[x] != bel[y]) { 85 if (deth[bel[x]] < deth[bel[y]]) swap(x,y); 86 ans = max(ans,query(2,n,1,pos[bel[x]],pos[x])); 87 x = fa[bel[x]]; 88 } 89 if (deth[x] > deth[y]) swap(x,y); 90 if (x != y) ans = max(ans,query(2,n,1,pos[x]+1,pos[y])); 91 return ans; 92 } 93 int main() { 94 char opt[15]; 95 int T;scanf("%d",&T); 96 while (T--) { 97 init(); 98 scanf("%d",&n); 99 for (int i=1; i<n; ++i) { 100 scanf("%d%d%d",&a[i],&b[i],&c[i]); 101 add_edge(a[i],b[i],c[i]); 102 add_edge(b[i],a[i],c[i]); 103 } 104 deth[1] = 1; 105 dfs1(1,0); 106 dfs2(1,1); 107 for (int i=1; i<n; ++i) { 108 if (deth[a[i]] > deth[b[i]]) data[pos[a[i]]] = c[i]; // 一定是pos 109 else data[pos[b[i]]] = c[i]; 110 } 111 build(2,n,1); 112 scanf("%s",opt); 113 while (opt[0]!='D') { 114 int x,y; 115 scanf("%d%d",&x,&y); 116 if (opt[0]=='Q') printf("%d\n",Ask(x,y)); 117 else Change(x,y); 118 scanf("%s",opt); 119 } 120 } 121 return 0; 122 }