Description
A tree of n nodes, numbered 1 to n, each node has a weight value w. We will take the following form to ask you this tree to perform some action: I. CHANGE ut: the junction of u right value to t II QMAX uv:. Nodes on the inquiry from point u to point v path the maximum weight III QSUM uv:. inquiry node u from point to point on the path weights and v Note: from point to point on the path node u v and v u itself comprises
Input
A first act input integer n, the number of nodes. Next, n - 1 lines of two integers a and B, expressed an edge connected between the node a and node b. Next n lines, each line an integer, the integer i-th row wi represents the weight of the node i. The next line 1, is an integer q, the total number of representations of operations. Next q lines of operation are given in the form of "CHANGE ut" or "QMAX uv" or "QSUM uv" is.
To 100% of the data, to ensure that 1 <= n <= 30000,0 < = q <= 200000; middle weights w ensure operation of each node between -30000 and 30000.
Output
For each operation "QMAX" or "QSUM", the output of each row represents an integer result output requirements.
Sample Input
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
Sample Output
1
2
2
10
6
5
6
5
16
Tree chain split
point right
single point modified
segment tree maintenance interval maximum value, and
#include <bits / STDC ++ H.> #define ULL unsigned Long Long the using namespace STD; const int N = 1E5 + 100 ; int n-, m, TOT, CNT; int FA [N], Last [N]; int Son [N ], deep [N], DFN [N], NUM [N], top [N]; // end node re-order sub-tree dfs son depth scale where the heavy chain int SUM [N * . 4 ], MX [N * . 4 ], W [N]; struct orz { int V, NEX;} E [N]; char OP [ 10 ]; void the init () { CNT = 0 ; TOT =0; memset(last,0,sizeof(last)); memset(son,-1,sizeof(son)); } void Insert(int x,int y) { cnt++; e[cnt].v=y; e[cnt].nex=last[x]; last[x]=cnt; } void dfs1(int x,int d,int pre) { fa[x]=pre; deep[x]=d; num[x]=1; for (int i=last[x];i;i=e[i].nex) { int v=e[i].v; if (v==fa[x]) continue; dfs1(v,d+1,x); num[x]+=num[v]; if (son[x]==-1 || num[v]>num[son[x]]) son[x]=v; } } void dfs2(int x,int sp) { top[x]=sp; dfn[x]=++tot; if (son[x]==-1) return ; dfs2(son[x],sp); for (int i=last[x];i;i=e[i].nex) { int v=e[i].v; if (v==fa[x]) continue; if (v!=son[x]) dfs2(v,v); } } void PushUp(int s) { sum[s]=sum[s<<1]+sum[s<<1|1]; mx[s]=max(mx[s<<1],mx[s<<1|1]); } void build(int s,int l,int r) { mx[s]=sum[s]=0; if (l==r) return ; int m=(l+r)>>1; build(s<<1,l,m); build(s<<1|1,m+1,r); PushUp(s); } void update(int s,int l,int r,int pos,int val) { if (l==r) { mx[s]=sum[s]=val; return ; } int mid=(l+r)>>1; if (pos<=mid) update(s<<1,l,mid,pos,val); else update(s<<1|1,mid+1,r,pos,val); PushUp(s); } int querymx(int s,int l,int r,int L,int R) { //printf("s=%d,l=%d,r=%d,L=%d,R=%d\n",s,l,r,L,R); if (L<=l&&r<=R) return mx[s]; int mid=(l+r)>>1; int ans=INT_MIN; if (L<=mid) ans=max(ans,querymx(s<<1,l,mid,L,R)); if (R>mid) ans=max(ans,querymx(s<<1|1,mid+1,r,L,R)); return ans; } int querysum(int s,int l,int r,int L,int R) { if (L<=l&&r<=R) return sum[s]; int mid=(l+r)>>1; int ans=0; if (L<=mid) ans+=querysum(s<<1,l,mid,L,R); if (R>mid) ans+=querysum(s<<1|1,mid+1,r,L,R); return ans; } void solve(int op,int x, int y) { if (op==1) { int mx=INT_MIN; while (top[x]!=top[y]) { if (deep[top[x]]<deep[top[y]]) swap(x, y); mx=max(mx,querymx(1,1,n,dfn[top[x]],dfn[x])); x=fa[top[x]]; } if (deep[x]>deep[y]) swap(x,y); mx=max(mx,querymx(1,1,n,dfn[x],dfn[y])); printf("%d\n",mx); } else { int ans=0; while (top[x]!=top[y]) { if (deep[top[x]]<deep[top[y]]) swap(x, y); ans+=querysum(1,1,n,dfn[top[x]],dfn[x]); x=fa[top[x]]; } if (deep[x]>deep[y]) swap(x,y); ans+=querysum(1,1,n,dfn[x],dfn[y]); printf("%d\n",ans); } } int main() { while (scanf("%d",&n)!=EOF) { init(); int u,v; for (int i=1;i<n;i++) { scanf("%d%d",&u,&v); Insert(u,v); Insert(v,u); } dfs1(1,0,0); //cout<<'*'<<endl; dfs2(1,1); build(1,1,n); for (int i=1;i<=n;i++) { scanf("%d",&u); update(1,1,n,dfn[i],u); } scanf("%d",&m); while (m--) { scanf("%s",op); if (op[0]=='C') { scanf("%d%d",&u,&v); update(1,1,n,dfn[u],v); } else { scanf("%d%d",&u,&v); if (op[1]=='M') solve(1,u,v); else solve(2,u,v); } } } return 0; }