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.
Suddenly I feel so weak ...
This question really tests your brain hole size.
First ORZHZW
For all the interval [l,r] of the number I, we put the tree from the root to I on the path of the point +1, then the query of the σlca[i,z] is the ROOT to Z of the tree on the path of the weight of the sum (this will be desired)
Then notice that the inquiry is offline and can be directly added and reduced.
So the output can be processed off-line after reading it.
For the interval (l,r,x) inquiry, the difference is divided into (1,r,x)-(1,L-1,X)
You can then join and process the query from 1 to N in turn
#include <cstdio> #include <iostream> #include <cstring> #include <cstdlib> #include < algorithm> #include <cmath> #include <deque> #include <set> #include <map> #include <ctime > #define LL long long#define INF 0x7ffffff#define pa pair<int,int> #define Pi 3.1415926535897932384626433832795028841971#define N 100010#define mod 201314using namespace Std;inline ll read () {ll x= 0,f=1;char Ch=getchar (); while (ch< ' 0 ' | | Ch> ' 9 ') {if (ch== '-') F=-1;ch=getchar ();} while (ch>= ' 0 ' &&ch<= ' 9 ') {x=x*10+ch-' 0 '; Ch=getchar ();} return x*f;} int n,m,cnt,cnt2,tt,now=1;struct edge{int To,next;} E[2*n];struct segtree{int L,r,sum,tag;} Tree[4*n];struct query{int Lim,lca,rnk,res;} q[200010];inline BOOL CMP (const query &a,const query &b) {return a.lim<b.lim;} int head[n];int mrk[n],son[n],depth[n],fa[n][21];int place[n],pplace[n],belong[n];int qrnk[100010];inline void Ins ( int U,int v) {e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;} Inline VOID Insert (int u,int v) {ins (u,v); ins (v,u);} inline void dfs1 (int x,int dep) {if (mrk[x]) return;mrk[x]=1;son[x]=1;depth[x]=dep;for (int i=1;i<=20;i++) fa[x][i]= fa[fa[x][i-1]][i-1];for (int i=head[x];i;i=e[i].next) if (!mrk[e[i].to]) {DFS1 (e[i].to,dep+1); son[x]+=son[e[i].to];}} inline void dfs2 (int x,int chain) {place[x]=++tt;pplace[tt]=x;belong[x]=chain;int mx=-1,res=-1;for (int i=head[x];i;i= E[i].next) if (E[i].to!=fa[x][0]) {if (SON[E[I].TO]>MX) {mx=son[e[i].to]; res=e[i].to; }}if (Res==-1) RETURN;DFS2 (Res,chain); for (int i=head[x];i;i=e[i].next) if (e[i].to!=res&&e[i].to!=fa[x][0]) DFS2 (e[i].to,e[i].to);} inline int LCA (int a,int b) {if (Depth[a]<depth[b]) swap (A, b), int res=depth[a]-depth[b];for (int i=0;i<=20;i++) if ( Res & (1<<i)) a=fa[a][i];for (int i=20;i>=0;i--) if (Fa[a][i]!=fa[b][i]) {a=fa[a][i]; B=fa[b][i]; }if (a==b) return A;return fa[a][0];} inline void update (int k) {tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;} Inline VOID pushdown (int k) {int tag=tree[k].tag;tree[k].tag=-1;if (tag==-1| | TREE[K].L==TREE[K].R) return; tree[k<<1].sum+= (tree[k<<1].r-tree[k<<1].l+1) *tag;tree[k<<1|1].sum+= (tree[k<<1|1 ].r-tree[k<<1|1].l+1) *tag;if (tree[k<<1].tag==-1) Tree[k<<1].tag=tag;else tree[k<<1].tag+ =tag;if (tree[k<<1|1].tag==-1) Tree[k<<1|1].tag=tag;else Tree[k<<1|1].tag+=tag;} inline void buildtree (int now,int l,int r) {tree[now].l=l;tree[now].r=r;tree[now].tag=-1;if (l==r) return;int mid= (l+r) >>1;buildtree (Now<<1,l,mid); Buildtree (now<<1|1,mid+1,r);} inline void add_in_tree (int now,int x,int y,int dat) {pushdown (now); int L=tree[now].l,r=tree[now].r;if (l==x&&r ==y) {tree[now].sum+= (r-l+1) *dat;tree[now].tag=dat;return;} int mid= (L+R) >>1;if (y<=mid) add_in_tree (now<<1,x,y,dat); else if (X>mid) Add_in_tree (now<<1| 1,x,y,dat); Else{add_in_tree (Now<<1,x,mid,dat); Add_in_tree (Now<<1|1,mid+1,y,dat);} UpdateNow);} inline int ask_in_tree (int now,int x,int y) {pushdown (now); int l=tree[now].l,r=tree[now].r;if (l==x&&r==y) Return Tree[now].sum;int mid= (l+r) >>1;if (Y<=mid) return Ask_in_tree (now<<1,x,y); else if (X>mid) Return Ask_in_tree (now<<1|1,x,y), Else return Ask_in_tree (now<<1,x,mid) +ask_in_tree (now<<1|1,mid +1,y);} inline void Add (int from,int to,int dat) {int l,r;while (Belong[from]!=belong[to]) {L=place[belong[from]];r=place[from] ; Add_in_tree (1,l,r,dat); from=fa[belong[from]][0];} L=place[to];r=place[from];add_in_tree (1,l,r,dat);} inline int Ask (int from,int to) {int l,r,s=0;while (Belong[from]!=belong[to]) {l=place[belong[from]];r=place[from];s= ( Ask_in_tree (1,l,r) +s)%mod;from=fa[belong[from]][0];} L=place[to];r=place[from];s= (S+ask_in_tree (1,l,r))%mod;return s;} int main () {n=read (); M=read (); for (int i=2;i<=n;i++) {fa[i][0]=read () +1;insert (fa[i][0],i);} DFS1 (;d fs2), Buildtree (1,1,n), for (int i=1;i<=m;i++) {int x=read () +1,y=read () +1,z=read () +1;Q[++CNT2].lim=x-1;q[cnt2].lca=z;q[cnt2].rnk=cnt2;q[++cnt2].lim=y;q[cnt2].lca=z;q[cnt2].rnk=cnt2;} Sort (q+1,q+2*m+1,cmp), while (q[now].lim==0) now++;for (int i=1;i<=n;i++) {Add (i,1,1), while (q[now].lim==i& &now<=2*m) {q[now].res=ask (q[now].lca,1); now++;}} for (int i=1;i<=2*m;i++) qrnk[q[i].rnk]=q[i].res;for (int i=1;i<=m;i++) printf ("%d\n", (qrnk[2*i]-qrnk[2*i-1]+ MoD)%mod);}
bzoj3626 [Lnoi2014]lca