Description
There are n nodes on a tree, numbered 1 to N, each with a weight of W.
We will ask you to do some work on this tree in the following form:
I. Change u t: Changing the weight of the node U to t
Ii. QMAX u V: ask for the maximum weight of the node on the path from point u to V
Iii. qsum u V: ask for the weights and values of the nodes on the path from point u to V
Note: Nodes on the path from point u to v include U and V itself
Input & Outputinput
The first behavior of the input file is an integer n, which represents the number of nodes.
The next n–1 line, with 2 integers a and b per line, indicates that there is an edge connected between Node A and Node B.
The next line is n integers, and the I integer WI indicates the weight of node I.
The next 1 lines, an integer q, represent the total number of operations.
The next Q line, one operation per line, is given in the form "Change U T" or "QMAX u V" or "Qsum u V".
Output
For each "QMAX" or "qsum" operation, each line outputs an integer representing the result of the required output.
Sampleinput
41 22 34 14 2 1 312QMAX 3 4QMAX 3 3QMAX 3 2QMAX 2 3QSUM 3 4QSUM 2 1CHANGE 1 5QMAX 3 4CHANGE 3 6QMAX 3 4QMAX 2 4QSUM 3 4
Output
412210656516
Solution
Porcelain single point modification, the path query maximum value, the path query point right and, compared to bare tree profile.
Fear is not a constant more than the Rokua (escape
Code:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include < cctype> #include <string>using std::min;using std::max;using std::swap;using std::isdigit;using std::memset; Using std::string;using std::cin;using std::cout;using std::endl;using std::ios;const int maxn = 30005;struct edge{int TO,NXT;} e[maxn<<1];struct node{int W,mx,tag; Node () {mx = w = tag = 0; }}TR[MAXN << 2];int lnk[maxn],edgenum;int top[maxn],size[maxn],dep[maxn],son[maxn],f[maxn],dfn[maxn],dfn2[ Maxn];int cnt;int w[maxn],v[maxn],n,m,q;void Add (int bgn,int end) {e[++edgenum].to = end; E[EDGENUM].NXT = LNK[BGN]; LNK[BGN] = edgenum;} void Dfs (int x,int fa,int d) {size[x] = 1; F[X] = FA; DEP[X] = D; for (int p = lnk[x]; p; p = e[p].nxt) {int y = e[p].to; if (y = = FA) continue; DFS (y, x, D + 1); SIZE[X] + = Size[y]; if (Size[y] > Size[son[x]]) son[x] = y; }}void DFS2 (int x,int init) {dfn[x] = ++cnt; W[CNT] = v[x]; TOP[X] = init; if (!son[x]) return; DFS2 (Son[x],init); for (int p = lnk[x]; p; p = e[p].nxt) {int y = e[p].to; if (y = = f[x]| | y = = Son[x]) continue; DFS2 (Y,y); }}void Build (int cur,int l,int R) {if (L = = r) {TR[CUR].W = w[l]; tr[cur].mx = W[l]; Return } int mid = (L + r) >> 1; Build (Cur<<1,l,mid); Build (Cur<<1|1,mid + 1,r); TR[CUR].W = TR[CUR<<1].W + tr[cur<<1|1].w; tr[cur].mx = max (tr[cur<<1].mx,tr[cur<<1|1].mx);} int querys (int cur,int l,int r,int l,int r) {int res = 0; if (l <= l && R >= R) {res + = TR[CUR].W; return res; } int mid = (l+r) >>1; if (l<=mid) res + = Querys (cur<<1,l,mid,l,r); if (r>mid) res + = Querys (cur<<1|1,mid+1,r,l,r); return res;} int Queryx (int cur,int l,int r,int l,int r) {int res =-214748; if (l <= l && R; = r) return tr[cur].mx; int mid = (l+r) >>1; if (l<=mid) res = max (res, Queryx (cur<<1,l,mid,l,r)); if (r>mid) res = max (res, Queryx (cur<<1|1,mid+1,r,l,r)); return res;} void pupdate (int cur,int l,int r,int p,int c) {if (L = = r) {TR[CUR].W = C; tr[cur].mx = C; Return } else{int mid = (l+r) >>1; if (P <= mid) pupdate (CUR<<1,L,MID,P,C); else Pupdate (CUR<<1|1,MID+1,R,P,C); TR[CUR].W = TR[CUR<<1].W + tr[cur<<1|1].w; tr[cur].mx = max (tr[cur<<1].mx,tr[cur<<1|1].mx); }}//---------------------------int queryts (int x,int y) {int ans = 0; while (top[x]! = Top[y]) {if (Dep[top[x]] < Dep[top[y]]) swap (x, y); Ans + = Querys (1,1,n,dfn[top[x]],dfn[x]); x = f[top[x]]; } if (Dep[x]>dep[y]) swap (x, y); Ans + = Querys (1,1,n,dfn[x],dfn[y]); return ans;} int querytx (int x,int y) {int ans =-214748; while (top[x]! = Top[y]) {if (Dep[top[x]] < dep[top[y]) swap (x, y); ans = max (ans, Queryx (1,1,n,dfn[top[x]],dfn[x)); x = f[top[x]]; } if (Dep[x] > Dep[y]) swap (x, y); ans = max (ans, Queryx (1,1,n,dfn[x],dfn[y)); return ans;} int main () {Ios::sync_with_stdio (false); string S; int x, y; CIN >> N; for (int i = 1; i < n; ++i) {cin >> x >> y; Add (x, y); Add (y,x); } for (int i = 1; I <= n; ++i) cin >> V[i]; DFS (1,0,1); DFS2 (a); Build (1,1,n); CIN >> Q; for (int i = 1; I <= Q; ++i) {cin >> S; if (s[0] = = ' C ') {cin >> x >> y; Pupdate (1,1,n,dfn[x],y); } else if (s[0] = = ' Q ' && s[1] = = ' M ') {cin >> x >> y; cout << Querytx (x, y) << Endl; } else {cin >> x >> y; cout << QuEryts (x, y) << Endl; }} return 0;}
[jsoi2008][bzoj1036] Tree statistics-tree chain split