Polycarpus got hold of a family relationship tree. The tree describes family relationships of n people, numbered 1 through n. Each person in the tree has no more than one parent.
Let’s call person a a 1-ancestor of person b, if a is the parent of b.
Let’s call person a a k-ancestor (k > 1) of person b, if person b has a 1-ancestor, and a is a (k - 1)-ancestor of b’s 1-ancestor.
Family relationships don’t form cycles in the found tree. In other words, there is no person who is his own ancestor, directly or indirectly (that is, who is an x-ancestor for himself, for some x, x > 0).
Let’s call two people x and y (x ≠ y) p-th cousins (p > 0), if there is person z, who is a p-ancestor of x and a p-ancestor of y.
Polycarpus wonders how many counsins and what kinds of them everybody has. He took a piece of paper and wrote m pairs of integers vi, pi. Help him to calculate the number of pi-th cousins that person vi has, for each pair vi, pi.
Input
The first input line contains a single integer
n
(
1
≤
n
≤
1
0
5
)
n (1 ≤ n ≤ 10^5)
n(1 ≤ n ≤ 105) — the number of people in the tree. The next line contains n space-separated integers r1, r2, …, rn, where
r
i
(
1
≤
r
i
≤
n
)
r_i (1 ≤ r_i ≤ n)
ri(1 ≤ ri ≤ n) is the number of person i’s parent or 0, if person i has no parent. It is guaranteed that family relationships don’t form cycles.
The third line contains a single number m ( 1 ≤ m ≤ 1 0 5 ) m (1 ≤ m ≤ 10^5) m(1 ≤ m ≤ 105) — the number of family relationship queries Polycarus has. Next m lines contain pairs of space-separated integers. The i-th line contains numbers v i , p i ( 1 ≤ v i , p i ≤ n ) v_i, p_i (1 ≤ v_i, p_i ≤ n) vi,pi(1 ≤ vi, pi ≤ n).
Output
Print m space-separated integers — the answers to Polycarpus’ queries. Print the answers to the queries in the order, in which the queries occur in the input.
Examples
input
6
0 1 1 0 4 4
7
1 1
1 2
2 1
2 2
4 1
5 1
6 1
output
0 0 1 0 0 1 1
这个题感觉挺绕的,就是给出的查询v和p,问的是以v的第p个祖先的这个子树下,有多少个和v一样深度的点。
所以实际上知道v以后,我们只需要知道他的祖先的是哪个点,直观上可以跑个暴力,显然超时,这里就用到了dsu on tree了,那么我们还需要知道附着在某个子树下的查询有多少个,开个vector就行了。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
#define ll long long
#define maxx 100005
#define INF 0x7f7f7f7f
using namespace std;
int n,m;
int head[maxx],to[maxx],_next[maxx];
int edge;
void addEdge(int x,int y)
{
to[++edge]=y,_next[edge]=head[x],head[x]=edge;
}
vector<pair<int ,int> >q[maxx];
vector<pair<int ,int> >_q[maxx];
int son[maxx];
int deep[maxx];
int _size[maxx];
int a[maxx],cnt;
void dfs1(int u)
{
a[++cnt]=u;
for(int i=0;i<q[u].size();i++)
{
if(q[u][i].first>=cnt)_q[0].push_back(q[u][i]);
else _q[a[cnt-q[u][i].first]].push_back(q[u][i]);//附着到某个子树的查询
}
_size[u]=1;
int maxson=-1;
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
deep[v]=deep[u]+1;
dfs1(v);
cnt--;
_size[u]+=_size[v];
if(maxson<_size[v])
{
son[u]=v;
maxson=_size[v];
}
}
}
int l[maxx],r[maxx],_index;
int b[maxx];
void dfs2(int u)
{
l[u]=++_index;
b[_index]=deep[u];
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
dfs2(v);
}r[u]=_index;
}
int ans[maxx];
int tot[maxx];
inline void del(int u)
{
for(int i=l[u];i<=r[u];i++)tot[b[i]]=0;
}
inline void add(int u)
{
for(int i=l[u];i<=r[u];i++)tot[b[i]]++;
}
void dfs(int u)
{
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
if(v==son[u])continue;
dfs(v);
del(v);
}
if(son[u])
{
dfs(son[u]);
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
if(v!=son[u])add(v);
}
}
if(u)
{
for(int i=0;i<_q[u].size();i++)
ans[_q[u][i].second]=tot[deep[u]+_q[u][i].first]-1;
}
else for(int i=0;i<_q[u].size();i++)
ans[_q[u][i].second]=0;
tot[deep[u]]++;
}
int main()
{
cin>>n;
int x,y;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
addEdge(x,i);
}
cin>>m;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
q[x].push_back(make_pair(y,i));
}
dfs1(0);
dfs2(0);
dfs(0);
for(int i=1;i<m;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[m]);
return 0;
}