树链剖分,点权,单点更改,路径查询。学树链剖分下面这个博文不错
http://blog.csdn.net/y990041769/article/details/40348013
线段树必须写的很熟练才行。注意负数
1 #include <cstdio> 2 #include <vector> 3 #include <algorithm> 4 5 using namespace std; 6 7 const int maxn = 3e4+10; 8 const int INF = 0x3f3f3f3f; 9 10 ///////////////////////////////////// 11 int topw; 12 int son[maxn],top[maxn],fa[maxn],siz[maxn],id[maxn],dep[maxn]; 13 int val[maxn],pre_val[maxn]; 14 15 vector<int> G[maxn]; 16 17 void dfs_1(int u,int f,int d) 18 { 19 son[u] = 0; 20 dep[u] = d; 21 fa[u] = f; 22 siz[u] = 1; 23 for(int i=0;i<G[u].size();i++) 24 { 25 int v = G[u][i]; 26 if(v == f) continue; 27 dfs_1(v,u,d+1); 28 siz[u] += siz[v]; 29 if(siz[son[u]] < siz[v]) 30 { 31 son[u] = v; 32 } 33 } 34 } 35 36 void dfs_2(int u,int tp) 37 { 38 top[u] = tp; 39 id[u] = ++topw; 40 if(son[u]) dfs_2(son[u],tp); 41 for(int i=0;i<G[u].size();i++) 42 { 43 int v = G[u][i]; 44 if(v == fa[u] || v == son[u]) continue; 45 dfs_2(v,v); 46 } 47 } 48 49 //////////////////////////////////// 50 #define lson l,m,rt<<1 51 #define rson m+1,r,rt<<1|1 52 #define root 1,topw,1 53 54 int sum[maxn<<2]; 55 int mx[maxn<<2]; 56 57 void push_up(int rt) 58 { 59 sum[rt] = sum[rt<<1]+sum[rt<<1|1]; 60 mx[rt] = max(mx[rt<<1],mx[rt<<1|1]); 61 } 62 63 void build(int l,int r,int rt) 64 { 65 sum[rt] = 0; 66 mx[rt] = 0; 67 if(l == r) 68 { 69 sum[rt] = val[l]; 70 mx[rt] = val[l]; 71 return ; 72 } 73 int m = (l+r)>>1; 74 build(lson); 75 build(rson); 76 push_up(rt); 77 } 78 79 void update(int pos,int add,int l,int r,int rt) 80 { 81 if(l == r) 82 { 83 sum[rt] = add; 84 mx[rt] = add; 85 return ; 86 } 87 int m = (l+r)>>1; 88 if(pos <= m) update(pos,add,lson); 89 else update(pos,add,rson); 90 push_up(rt); 91 } 92 93 int query_sum(int L,int R,int l,int r,int rt) 94 { 95 if(L <= l && R >= r) 96 { 97 return sum[rt]; 98 } 99 int m = (l+r)>>1 , ans = 0; 100 if(L <= m) ans += query_sum(L,R,lson); 101 if(R > m) ans += query_sum(L,R,rson); 102 return ans; 103 } 104 105 int query_max(int L,int R,int l,int r,int rt) 106 { 107 if(L <= l && R >= r) 108 { 109 //printf("[%d,%d] rt:%d mx:%d ",l,r,rt,mx[rt]); 110 return mx[rt]; 111 } 112 int m = (l+r)>>1 , ans = -INF; 113 if(L <= m) ans = max(ans,query_max(L,R,lson)); 114 if(R > m) ans = max(ans,query_max(L,R,rson)); 115 return ans; 116 } 117 118 int Find_sum(int u,int v) 119 { 120 int fu = top[u],fv = top[v]; 121 int ans = 0; 122 while(fu != fv) 123 { 124 //printf("ans:%d %d %d %d %d ",ans,u,fu,v,fv); 125 if(dep[fu] < dep[fv]) 126 { 127 swap(u,v); 128 swap(fu,fv); 129 } 130 ans += query_sum(id[fu],id[u],root); 131 u = fa[fu]; 132 fu = top[u]; 133 } 134 if(u == v) 135 { 136 return ans+query_sum(id[u],id[v],root); 137 } 138 else{ 139 if(dep[u] < dep[v]) swap(u,v); 140 return ans+query_sum(id[v],id[u],root); 141 } 142 } 143 144 int Find_max(int u,int v) 145 { 146 int fu = top[u],fv = top[v]; 147 int ans = -INF; 148 while(fu != fv) 149 { 150 if(dep[fu] < dep[fv]) 151 { 152 swap(u,v); 153 swap(fu,fv); 154 } 155 //printf("ans:%d %d %d %d %d ",ans,u,fu,v,fv); 156 //printf("q:%d ",query_max(id[fu],id[u],root)); 157 ans = max(ans,query_max(id[fu],id[u],root)); 158 u = fa[fu]; 159 fu = top[u]; 160 } 161 if(u == v) 162 { 163 return max(ans,query_max(id[u],id[v],root)); 164 } 165 else{ 166 if(dep[u] < dep[v]) swap(u,v); 167 return max(ans,query_max(id[v],id[u],root)); 168 } 169 } 170 171 ////////////////////////////////////////// 172 173 int N,Q; 174 int main() 175 { 176 freopen("input.in","r",stdin); 177 while(~scanf("%d",&N)) 178 { 179 for(int i=1,u,v;i<N;i++) 180 { 181 scanf("%d%d",&u,&v); 182 G[u].push_back(v); 183 G[v].push_back(u); 184 } 185 for(int i=1;i<=N;i++) scanf("%d",&pre_val[i]); 186 topw = 0; 187 dfs_1(1,0,1); 188 dfs_2(1,1); 189 for(int i=1;i<=N;i++) val[id[i]] = pre_val[i]; 190 build(root); 191 192 scanf("%d",&Q); 193 char op[10]; 194 int a,b; 195 while(Q--) 196 { 197 scanf("%s%d%d",op,&a,&b); 198 if(op[0] == 'Q') 199 { 200 if(op[1] == 'M') 201 { 202 printf("%d ",Find_max(a,b)); 203 }else 204 { 205 printf("%d ",Find_sum(a,b)); 206 } 207 }else 208 { 209 update(id[a],b,root); 210 } 211 } 212 for(int i=0;i<=N;i++) G[i].clear(); 213 } 214 }