3626: [Lnoi2014]lca time limit:10 Sec Memory limit:128 MB
submit:2050 solved:817
[Submit] [Status] [Discuss] Description
Give a root tree of n nodes (numbered 0 to n-1 and the root node to 0). The depth of a point is defined as the distance from the node to the root +1.
Set Dep[i] represents the depth of point I, LCA (I,J) represents the nearest public ancestor of I and J.
There are Q times to ask, each time asked to give L R Z, Beg Sigma_{l<=i<=r}dep[lca (i,z)].
(i.e., the sum of the depth of the nearest common ancestor of each node I and z within the [l,r] interval)
Input
The first line is 2 integers n Q.
The next n-1 line, which represents the parent node number of point 1 to N-1, respectively.
Next Q line, 3 integers per line l R Z.
Output
Output Q line, each line represents an answer to the query. 201314 modulo output for each answer
Sample Input5 2
0
0
1
1
1 4 3
1 4 2
Sample Output8
5
HINT
A total of 5 sets of data, the size of N and Q are 10000,20000,30000,40000,50000 respectively.
Source
Data has been strengthened by Saffah
Orz Gconeice
Obviously, the complexity of solving the violence is unbearable.
Considering this kind of violence, we mark all the points on Z to the root, and for the points between L and R, search up to the first labeled point to find out its depth statistic answer. It is observed that the depth is actually a few marked points (including itself) above. So, we may as well put Z to the root of the path on the point all +1, for the points between L and R to ask them to the root path on the point of the right and. Careful observation of the above violence is not difficult to find, in fact, the operation is additive, and reversible. That is to say, we can point to the L to R, point I to the root of the path on all +1, instead of asking Z to the root of the path of the point (including itself) the weights and is the answer to this query. To calculate the answer by asking the difference, that is, [1, R]−[1, l−1], we have a clear solution now. From 0 to n−1, insert point I, and the point on the path from I to the root is all +1. Ask for answers offline. We now need a data structure to maintain the sum of paths and paths, and obviously the tree-chain or LCT can accomplish this task. The complexity of the tree chain is O ((n + q) log n log n), and the complexity of the LCT is O ((n + q) log n), which can accomplish the task. So far, the topic has been solved by us perfectly.
The LCA of z can only be counted on the path from Z to root, and each point on the path to the root is taken as an LCA several times
Very ingenious conversion, [L,r] all points to root path +1, then ask Z to root path weights
Obviously, the tree chain splits
For multiple groups of queries, consider going to ask for differential, [1, R]−[1, l−1], and then go offline to ask for two endpoints, each add to a now will L-1 or R is now to ask questions
////main.cpp//bzoj4196////Created by Candy on 2017/1/2.//copyright©2017 year Candy. All rights reserved.//#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespacestd;#defineLC O<<1#defineRC O<<1|1#defineM ((l+r) >>1)#defineLson o<<1,l,m#defineRson O<<1|1,m+1,rConst intn=1e5+5, mod=201314; typedefLong LongLl;inlineintRead () {CharC=getchar ();intx=0, f=1; while(c<'0'|| C>'9'){if(c=='-') f=-1; C=GetChar ();} while(c>='0'&&c<='9') {x=x*Ten+c-'0'; C=GetChar ();} returnx*F;}intN,q,u,l,r;Chars[ -];structques{intZ,al,ar;} Q[n];structque{intX,ID,ISL; BOOL operator< (ConstQue &r)Const{returnx<r.x;}} A[n];intp;structedge{intv,ne,c,f;} E[n<<1];intCnt,h[n];inlinevoidInsintUintv) {CNT++; E[CNT].V=v;e[cnt].ne=h[u];h[u]=CNT;}intDeep[n],fa[n],tid[n],tot,top[n],mx[n],size[n];voidDfsintu) {Size[u]=1; for(intI=h[u];i;i=e[i].ne) { intv=e[i].v; if(V==fa[u])Continue; FA[V]=u;deep[v]=deep[u]+1; DFS (v); Size[u]+=Size[v]; if(Size[v]>size[mx[u]]) mx[u]=W; }}voidDfsintUintANC) { if(!u)return; Tid[u]=++tot; Top[u]=ANC; DFS (MX[U],ANC); for(intI=h[u];i;i=e[i].ne)if(e[i].v!=mx[u]&&e[i].v!=Fa[u]) DFS (E[I].V,E[I].V);}structnode{intSum,add;} T[n<<2];inlinevoidMergeinto) {T[o].sum=t[lc].sum+T[rc].sum;} InlinevoidPaintintOintLintRintd) {T[o].sum+=d* (r-l+1); T[o].add+=D;} InlinevoidPushdown (intOintLintR) { if(t[o].add) {paint (Lson,t[o].add); Paint (Rson,t[o].add); T[o].add=0; }}inlinevoidSegadd (intOintLintRintQlintQrintD) {//printf ("Add%d%d%d\n", o,l,r); if(ql<=l&&r<=qr) paint (o,l,r,d); Else{pushdown (o,l,r); if(ql<=m) Segadd (LSON,QL,QR,D); if(m<qr) segadd (rson,ql,qr,d); Merge (o); }}inlineintSegque (intOintLintRintQlintQR) {//printf ("Que%d%d%d%d%d\n", O,L,R,QL,QR); if(QL<=L&&R<=QR)returnt[o].sum; Else{pushdown (o,l,r); intans=0; if(ql<=m) ans+=Segque (LSON,QL,QR); if(M<QR) ans+=Segque (RSON,QL,QR); returnans; }}voidBuildintOintLintR) { if(l==r) Paint (o,l,r,0); Else{build (Lson); Build (Rson); }}voidAddintXintYintd) { while(top[x]!=Top[y]) { if(deep[top[x]]<Deep[top[y]]) swap (x, y); Segadd (1,1, n,tid[top[x]],tid[x],d); X=Fa[top[x]]; } if(tid[x]>Tid[y]) swap (x, y); Segadd (1,1, n,tid[x],tid[y],d);}intQueryintXinty) { intans=0; while(top[x]!=Top[y]) { if(deep[top[x]]<Deep[top[y]]) swap (x, y); Ans+=segque (1,1, N,tid[top[x]],tid[x]); ans%=MOD; X=Fa[top[x]]; } if(tid[x]>Tid[y]) swap (x, y); Ans+=segque (1,1, N,tid[x],tid[y]); ans%=MOD; returnans;}intMain () {n=read (); q=read (); for(intI=2; i<=n;i++) U=read () +1, Ins (u,i); DFS (1);d FS (1,1); Build (1,1, N); for(intI=1; i<=q;i++) {L=read (); R=read () +1; Q[i].z=read () +1; a[++p].x=l;a[p].id=i;a[p].isl=1; a[++p].x=r;a[p].id=i;a[p].isl=0; } sort (A+1, A +1+p); intnow=1; for(intI=1; i<=p;i++) {//printf ("A%d%d%d\n", A[I].X,A[I].ID,A[I].ISL); while(now<=a[i].x) Add (1, now,1), now++; int_=a[i].id; if(A[I].ISL) Q[_].al=query (1, q[_].z); ElseQ[_].ar=query (1, q[_].z); } for(intI=1; i<=q;i++) printf ("%d\n", (q[i].ar-q[i].al+mod)%MOD);}
Online words can be used with the Chairman tree, in the DFS sequence to build the Chairman tree
So the gap between each segment tree and the historical version is a node, that is, a point to the root of the path, there is a Logn segment, each segment has logn new nodes, complexity log^2n
Good trouble and a sign.
[2017-01-04 00:01:51]
I'm too weak, not m or R, not playing.
Bzoj 3626: [LNOI2014]LCA [Tree chain Split Line | Chairman Tree]