Preprocessing the number of sub nodes of each node sons, then the query to X can be obtained by sons[x]-Sigma (Sons[v) (V is the point to X distance to D)
How to find these v quickly? Notice that the point from X to D is definitely on the same level as the tree ....
You can record each node timestamp while the tree is DFS and save the nodes of each layer. Then maintain a prefix for each layer and if V is x under the face node then V's timestamp must be within the range of X, so that the prefix and range can be determined by two points ....
1414:query on a tree
Time Limit:3 Sec Memory limit:128 MB
submit:78 solved:23
[Submit] [Status] [Web Board]
Description
You are are given a rooted tree with N nodes indexed by 1, 2, ..., N, and the root is indexed by 1. We'll ask you to perform some queries of the following form:
X d:ask for how many nodes there are in the subtree rooted at x, such this distance between it and X is less than D.
Assume the length of each edge is 1.
Input
The ' the ' I line contains ' an integer t (T > 0), giving the number of test cases.
For the all test case, the ' the ' the ' contains ' an integer N (2≤n≤105). The next line contains N-1 integers f2, F3, ..., FN (1≤f2, F3, ..., fn≤n), where fi (2≤i≤n) denotes the Father O f i is fi. Then follows a line with an integer M (1≤m≤105) giving the number of queries. Then follow m lines with two integers x, D (1≤x, d≤n), giving the M queries.
Output
For each query, output how many nodes there are on subtree rooted at x, such this distance between it and X is Les S than D.
Sample Input
More Wonderful content: http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/
1
9
1 2 2 4 4 2 1 8
6
1 1
1 2
1 3
2 3
2 4
3 2
Sample Output
1
3
7
6
6
1
HINT
Source
The eighth session of university Students ' program design competition
[Submit] [Status] [Webboard]
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include &l
T;vector> using namespace std;
const int maxn=110000;
struct Edge {int to,next;
}EDGE[MAXN];
int adj[maxn],size;
Vector<int> EG[MAXN];
Vector<int> PRE_SUM[MAXN];
int dfn[maxn][2],sons[maxn],max_deep[maxn],deep[maxn],id[maxn],ti,maxdeep,n;
void init (int n) {size=0;
memset (adj,-1,sizeof (ADJ));
memset (dfn,0,sizeof (DFN));
Memset (Sons,0,sizeof (sons));
memset (deep,0,sizeof (Deep));
Memset (id,0,sizeof (id));
memset (max_deep,0,sizeof (max_deep));
Ti=0;maxdeep=0;
for (int i=0;i<=n+20;i++) {pre_sum[i].clear (), Pre_sum[i].push_back (0);
Eg[i].clear (), Eg[i].push_back (0);
} void Add_edge (int u,int v) {edge[size].to=v;
Edge[size].next=adj[u];
adj[u]=size++; } void DFS (int u,int Deep) {Dfn[u][0]=++ti;
Maxdeep=max (Maxdeep,deep);
Eg[deep].push_back (U);
int maxd=0;
for (int i=adj[u];~i;i=edge[i].next) {int v=edge[i].to;
DFS (v,deep+1);
Maxd=max (Maxd,max_deep[v]);
} max_deep[u]=maxd+1;
Deep[u]=deep;
Dfn[u][1]=ti;
sons[u]=dfn[u][1]-dfn[u][0]+1; } void Prefix_sum () {for (int i=1;i<=maxdeep;i++) {for (int j=1,sz=eg[i].size (); j<s
z;j++) {id[eg[i][j]]=j;
Pre_sum[i].push_back (Pre_sum[i][j-1]+sons[eg[i][j]]); } void Debug () {for (int i=1;i<=n;i++) {cout<<i<< "ST:" <&
lt;dfn[i][0]<< "ET:" <<dfn[i][1]<< "sons:" <<sons[i]<<endl;
} cout<< "Maxdeep:" <<maxdeep<<endl;
for (int i=1;i<=maxdeep;i++) {cout<<i<< ":" <<endl; FoR (int j=0,sz=eg[i].size (); j<sz;j++) {cout<<eg[i][j]<< ",";
} cout<<endl;
} cout<< "ID: \ n";
for (int i=1;i<=maxdeep;i++) {cout<<i<< ":" <<endl;
for (int j=0,sz=eg[i].size (); j<sz;j++) {cout<<id[eg[i][j]]<< ",";
} cout<<endl;
} cout<< "Prefix_sum: \ n";
for (int i=1;i<=maxdeep;i++) {cout<<i<< ":" <<endl;
for (int j=0,sz=eg[i].size (); j<sz;j++) {cout<<pre_sum[i][j]<< ",";
} cout<<endl;
} cout<< "Max_deep:";
for (int i=1;i<=n;i++) {cout<<i<< ":" <<max_deep[i]<<endl;
} void Solve (int x,int d) {int nowd=deep[x]; if (D>=max_deep[x]) {printf ("%d\n", sons[x]);
return;
int qd=nowd+d;
The left and right interval int l=0,r=0,sz=eg[qd].size ();
int Low,mid,high;
.. get-left POS low=0,high=sz-1;
while (Low<=high) {mid= (Low+high)/2;
int Ps=eg[qd][mid];
if (Dfn[ps][0]>=dfn[x][0]) {l=eg[qd][mid-1]; high=mid-1;
else low=mid+1;
///...get right POS low=0,high=sz-1;
while (Low<=high) {mid= (Low+high)/2;
int Ps=eg[qd][mid];
if (Dfn[ps][1]<=dfn[x][1]) {r=ps; low=mid+1;
else high=mid-1;
printf ("%d\n", Sons[x]-pre_sum[qd][id[r]]+pre_sum[qd][id[l]);
int main () {int t_t;
scanf ("%d", &t_t);
while (t_t--) {scanf ("%d", &n);
Init (n+1);
for (int i=2;i<=n;i++) {int fa; scanf ("%d", &FA);
Add_edge (Fa,i);
DFS (1,1);
Prefix_sum ();
Debug ();
int q;
scanf ("%d", &q);
while (q--) {int x,d;
scanf ("%d%d", &x,&d);
Solve (X,D);
} return 0; }