"BZOJ3653" laughing description set T for a tree with a root tree, we do the following definition:? Set A and B as two different nodes in T. If a is the ancestor of B, then it is said that "a than B does not know where the gaoming went". Set A and B as two different nodes in T. If the distance between A and B does not exceed a given constant x in the tree, then "A and B" is called "laughing". Given a root tree t of n nodes, the nodes are numbered 1 to n and the root node is node # 1th. You need to answer Q a question, ask the given two integers p and K, and ask how many ordered triples (A;B;C) satisfy: 1. A, B and C are three different points in T, and A is P node; 2. A and B are better than C do not know where to go; 3. A and B are laughing. The constant in the laughing here is the given K. The first line of input contains two positive integers n and q, each representing the number of points and queries that have a root tree. Next n-1 lines, each line describes an edge on a tree. Each row contains two integers u and V, which represents an edge between the node U and v. Next the Q line, each line describes an operation. Line I contains two integers representing the p and K of the I inquiry respectively. 1<=p<=n1<=k<=nn<=300000q<=300000output
Output Q line, each line corresponding to a query, representative of the answer to the question.
Sample Input5 3
1 2
1 3
2 4
4 5
2 2
4 1
2 3Sample Output3
1
3
The puzzle: If A and b are identified, then the number of C is the common subtree size of a and B-1, so we consider the contribution of all B.
Consider the case of B not in the A subtree, then B can only be on a to root path, which is clearly calculated directly.
So considering B in the case of a subtree, the equivalent of the depth of B and the DFS sequence are in a range, which can be regarded as a two-dimensional point problem, with the offline + tree array easy to solve.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm>using namespace Std;const int maxn=300010;typedef Long long ll;int n,m,cnt;int to[maxn<<1],next[maxn<<1],head[maxn],dep[ Maxn],siz[maxn],fa[maxn],p1[maxn],p2[maxn],p[maxn];ll s[maxn],ans[maxn];struct node{int x,k,org;} q[maxn];inline Int Rd () {int Ret=0,f=1;char gc=getchar (); while (gc< ' 0 ' | | Gc> ' 9 ') {if (gc== '-') F=-f;gc=getchar ();} while (gc>= ' 0 ' &&gc<= ' 9 ') ret=ret*10+ (gc^ ' 0 '), Gc=getchar (); return ret*f;} inline void Add (int a,int b) {to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;} void Dfs (int x) {siz[x]=1,p1[x]=++p2[0];for (int i=head[x];i!=-1;i=next[i]) if (to[i]!=fa[x]) fa[to[i]]=x,dep[to[i]]= Dep[x]+1,dfs (To[i]), Siz[x]+=siz[to[i]];p 2[x]=p2[0];} BOOL CMPQ (const node &a,const node &b) {return A.K<B.K;} BOOL Cmpp (const int &a,const int &b) {return dep[a]<dep[b];} inline void updata (int x,int v) {for (int i=x;i<=n;i+=i&-i) s[i]+=v;} inline ll query (int x) {ll ret=0;for (int i=x;i;i-=i&-i) ret+=s[i];return ret;} int main () {n=rd (), M=RD (), int i,j,a,b;memset (head,-1,sizeof (head)), for (i=1;i<n;i++) a=rd (), B=rd (), add (A, B), add ( B,a);d Ep[1]=1,dfs (1), for (i=1;i<=m;i++) q[i].x=rd (), Q[i].k=rd (), ans[i]= (LL) (min (DEP[Q[I].X]-1,Q[I].K)-1) * (siz [q[i].x]-1), Q[i].k+=dep[q[i].x],q[i].org=i;sort (Q+1,Q+M+1,CMPQ); for (i=1;i<=n;i++) P[i]=i;sort (p+1,p+n+1,cmpp ); for (i=j=1;i<=m;i++) {for (;d ep[p[j]]<=q[i].k&&j<=n;j++) updata (p1[p[j]],siz[p[j]]-1); Ans[q[i]. Org]+=query (p2[q[i].x])-query (p1[q[i].x]-1);} for (i=1;i<=m;i++) printf ("%lld\n", Ans[i]); return 0;}
"BZOJ3653" laughing off-line + tree-like array +dfs sequence