Statistics count for "Bzoj 1036" tree (tree-chain split)
1036: Count of [ZJOI2008] trees Time Limit: ten Sec Memory Limit: 162 MB
Submit: 12991 Solved: 5233
Description
There are n nodes on a tree, numbered 1 to N, each with a weight of W. We will ask you to complete this tree in the following form
Some operations: I. Change u t: Changing the weight of the node U to t ii. QMAX U V: asks for the maximum weight of the node on the path from point u to V
II. qsum u V: ask for the weights of the nodes on the path from point U to V and note that nodes on the path from point u to v include U and V itself
Input
The first behavior of the input 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 between Node A and Node B there is
An edge is connected. Next n rows, one integer per line, and the integer of line I, WI represents the weight of node I. The next 1 lines, an integer q, represent the action
of the total. The next Q line, one operation per line, is given in the form "Change U T" or "QMAX u V" or "Qsum u V".
For 100% data, ensure that the weight of each node in the 1<=n<=30000,0<=q<=200000; midway operation is between 30000 and 30000.
Output
For each "QMAX" or "qsum" operation, each line outputs an integer representing the result of the required output.
Sample Input
4
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 4Sample Output
4
1
2
2
10
6
5
6
5
-
Tree split Board problem, Rusty unexpectedly in line segment Rime =. =gg ...
Shun found a small thing, the query interval when actually do not press the depth of the chain to check.
The DFS sequence is on the line.
The code is as follows:
#include <iostream>#include <cmath>#include <vector>#include <cstdlib>#include <cstdio>#include <cstring>#include <queue>#include <stack>#include <list>#include <algorithm>#include <map>#include <set>#define LL Long Long#define PR pair<int,int>#define FREAD (CH) freopen (CH, "R", stdin)#define FWRITE (CH) freopen (CH, "w", stdout)Using namespace Std;constintINF =0x3f3f3f3f; constintMSZ =10000; constintMoD =1e9+7; Const DOUBLE EPS =1E-8; struct edge{intVNext;};intbit[2][233333];inthead[33333];intttp[33333],dfn[33333],nxt[33333],pre[33333]; Edge eg[66666];intTp,n,tim;void Add (intUintV) {eg[tp].v = v; EG[TP].Next= Head[u]; Head[u] = tp++;}intDFS1 (intUintPre) {intVintMX =0, id,tmp,cnt; id = u; CNT =1; for(inti = Head[u]; I! =-1; i = Eg[i].Next) {v = eg[i].v;if(v = = Pre)Continue; TMP = DFS1 (v,u); CNT + = tmp;//printf("%d-%d %d\ n", u,v,tmp);if(MX < TMP) {MX = tmp; id = v; }} Nxt[u] = ID;returnCNT;} void Dfs2 (intUintprintBOS) {Dfn[u] = tim++; PRE[U] = PR; Ttp[u] = BOS;intVif(Nxt[u] = = u)return; DFS2 (Nxt[u],u,bos); for(inti = Head[u]; I! =-1; i = Eg[i].Next) {v = eg[i].v;if(v = = PR | | v = = Nxt[u])Continue; DFS2 (V,U,V); }}void Change (intRootintLintRint POS,int x){if(L = = r) {bit[0][root] = bit[1][root] =x;return; }intMid = (l+r) >>1;if(Mid >=POS) Change (root<<1, L,mid,POS,x);ElseChange (root<<1|1, mid+1RPOS,x); bit[0][root] = bit[0][root<<1]+bit[0][root<<1|1]; bit[1][root] = max (bit[1][root<<1],bit[1][root<<1|1]);}intSum (intRootintLintRintllintRR) {//printf("%d %d%d \ n", l,r,bit[0][root]);if(L = = ll && r = = RR)returnbit[0][root];intMid = (l+r) >>1;if(Mid >= RR)returnSum (root<<1, L,MID,LL,RR);Else if(mid+1<= ll)returnSum (root<<1|1, mid+1, R,LL,RR);Else returnSum (root<<1, L,mid,ll,mid) +sum (root<<1|1, mid+1, r,mid+1, RR);}intMax (intRootintLintRintllintRR) {if(L = = ll && r = = RR)returnbit[1][root];intMid = (l+r) >>1;if(Mid >= RR)returnMax (root<<1, L,MID,LL,RR);Else if(mid+1<= ll)returnMax (root<<1|1, mid+1, R,LL,RR);Else returnMax (Max (root<<1, L,mid,ll,mid), Max (root<<1|1, mid+1, r,mid+1, RR));} void Solve (char ch,intAintb) {if(ch = =' H ') Change (1,0, N-1, dfn[a],b);Else if(ch = =' M ') {intans =-inf; while(ttp[b]! = Ttp[a]) {if(Dfn[b] < dfn[a]) swap (b,a);//printf("%d- %d %d-%d", Ttp[b],b,dfn[ttp[b]],dfn[b]); ans = max (Ans,max (1,0, N-1, Dfn[ttp[b]],dfn[b])); b = Pre[ttp[b]]; }if(Dfn[b] < dfn[a]) swap (b,a);if(a) ans = max (Ans,max (1,0, N-1, Dfn[a],dfn[b]));printf("%d\ n", ans); }Else{intAns =0; while(ttp[b]! = Ttp[a]) {if(Dfn[b] < dfn[a]) swap (b,a);//printf("%d- %d %d-%d\ n", Ttp[b],b,dfn[ttp[b]],dfn[b]); Ans + = Sum (1,0, N-1, Dfn[ttp[b]],dfn[b]); b = Pre[ttp[b]]; }if(Dfn[b] < dfn[a]) swap (b,a);if(a) {//printf("%d- %d %d-%d\ n", A,b,dfn[a],dfn[b]); Ans + = Sum (1,0, N-1, Dfn[a],dfn[b]); }printf("%d\ n", ans); }}intMain () {//fread("In.in");//fwrite("Run.out");intU,v,x; while(~SCANF ("%d", &n)) {memset (head,-1, sizeof (head)); TP =0; for(inti =1; I < n; ++i) {scanf ("%d%d", &u,&v); ADD (U,V); ADD (V,u); } DFS1 (1,1); ttp[0] =1; Tim =0; DFS2 (1,0,1); memset (bit,0, sizeof (bit)); for(inti =1; I <= N; ++i) {scanf ("%d",&x);//printf("%d: fa:%d dfn:%d top:%d\ n", I,pre[i],dfn[i],ttp[i]); Change (1,0, N-1, Dfn[i],x); }int m; Char opt[6];intb; scanf"%d",&m); while(m--) {scanf ("%s%d%d", opt,&a,&b); Solve (opt[1],A,B); } }return 0;}
Statistics count for "Bzoj 1036" tree (tree-chain split)