SPOJ QTREE-Query on a tree-树链剖分-边权
用每个点代表父节点到此点的边。建立一一映射后就可以用点权的方法处理了。
注意的是路径两端节点的处理
1 #include <cstdio> 2 #include <algorithm> 3 #include <vector> 4 5 using namespace std; 6 7 const int maxn = 1e5+5; 8 int val[maxn],dep[maxn],siz[maxn],top[maxn],id[maxn],son[maxn],fa[maxn]; 9 int topw,M; 10 11 vector<int> G[maxn]; 12 struct Edge{ 13 int x,y,val; 14 }e[maxn]; 15 16 void dfs_1(int u,int f,int d) 17 { 18 fa[u] = f; 19 son[u] = 0; 20 siz[u] = 1; 21 dep[u] = d; 22 23 for(int i=0;i<G[u].size();i++) if(G[u][i] != f ) 24 { 25 dfs_1(G[u][i],u,d+1); 26 siz[u] += siz[G[u][i]]; 27 if(siz[son[u] ] < siz[G[u][i] ]) 28 { 29 son[u] = G[u][i]; 30 } 31 } 32 } 33 34 void dfs_2(int u,int tp) 35 { 36 top[u] = tp; 37 id[u] = ++topw; 38 if(son[u]) dfs_2(son[u],tp); 39 for(int i=0;i<G[u].size();i++) if(G[u][i] != fa[u] && G[u][i] != son[u]) 40 { 41 dfs_2(G[u][i],G[u][i]); 42 } 43 } 44 45 int N,T; 46 47 void debug() 48 { 49 for(int i=1;i<=N;i++) 50 { 51 printf("%d siz:%d son:%d dep:%d fa:%d ",i,siz[i],son[i],dep[i],fa[i]); 52 printf("top:%d id:%d\n",top[i],id[i]); 53 } 54 } 55 56 /*-------------------------------------*/ 57 //segment Tree 58 #define lson(x) (x<<1) 59 #define rson(x) (x<<1|1) 60 61 struct SegmentTree{ 62 int l,r,val; 63 }sgtree[4*maxn]; 64 65 void pushup(int x) 66 { 67 sgtree[x].val = max(sgtree[lson(x)].val,sgtree[rson(x)].val); 68 } 69 70 void Build(int l,int r,int x) 71 { 72 sgtree[x].l = l; 73 sgtree[x].r = r; 74 if(l==r) 75 { 76 sgtree[x].val = val[l]; 77 return ; 78 } 79 int mid = (l+r)>>1; 80 Build(l,mid,lson(x)); 81 Build(mid+1,r,rson(x)); 82 pushup(x); 83 } 84 85 void update(int x,int v,int add) 86 { 87 if(sgtree[x].l == sgtree[x].r) 88 { 89 sgtree[x].val = add; 90 //printf("change:%d %d\n",v,sgtree[x].l); 91 return ; 92 } 93 int mid = (sgtree[x].l+sgtree[x].r)>>1; 94 if(v <= mid) update(lson(x),v,add); 95 else update(rson(x),v,add); 96 pushup(x); 97 } 98 99 int query(int x,int l,int r) 100 { 101 if(sgtree[x].l >= l && sgtree[x].r <= r) 102 { 103 return sgtree[x].val; 104 } 105 int mid = (sgtree[x].l+sgtree[x].r)>>1; 106 int ans = 0; 107 if(l <= mid) ans = max(ans,query(lson(x),l,r)); 108 if(r > mid) ans = max(ans,query(rson(x),l,r)); 109 return ans; 110 } 111 112 int Find(int u,int v) 113 { 114 int ans = 0,fu = top[u],fv = top[v]; 115 while(fu != fv) 116 { 117 if(dep[fu] < dep[fv]) 118 { 119 swap(fu,fv);swap(u,v); 120 } 121 ans = max(ans,query(1,id[fu],id[u])); 122 u = fa[fu]; 123 fu = top[u]; 124 } 125 if(u == v) return ans; 126 if(dep[u]>dep[v]) swap(u,v); 127 return max(ans,query(1,id[son[u] ],id[v])); 128 } 129 130 int main() 131 { 132 //freopen("input.in","r",stdin); 133 scanf("%d",&T); 134 while(T--) 135 { 136 scanf("%d",&N); 137 for(int i=1,a,b,c;i<N;i++) 138 { 139 scanf("%d%d%d",&a,&b,&c); 140 e[i].x = a; 141 e[i].y = b; 142 e[i].val = c; 143 G[a].push_back(b); 144 G[b].push_back(a); 145 } 146 topw = 0; 147 dfs_1(1,0,1); 148 dfs_2(1,1); 149 //debug(); 150 151 for(int i=1;i<N;i++) 152 { 153 if(dep[e[i].x] < dep[e[i].y]) swap(e[i].x,e[i].y); 154 val[id[e[i].x]] = e[i].val; 155 } 156 157 Build(1,topw,1); 158 char op[100]; 159 while(scanf("%s",op) && op[0] != 'D') 160 { 161 int a,b; 162 scanf("%d%d",&a,&b); 163 if(op[0] == 'Q') 164 printf("%d\n",Find(a,b)); 165 else if(op[0] == 'C') 166 update(1,id[e[a].x],b); 167 } 168 169 for(int i=1;i<=N;i++) G[i].clear(); 170 } 171 }