http://codeforces.com/contest/1006/problem/E

E. Military Problem
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

In this problem you will have to help Berland army with organizing their command delivery system.

There are a.

Officer y if one of the following conditions holds:

  • officer x;
  • the direct superior of officer y.

For example, on the picture below the subordinates of the officer 5,6,7,8,9.

The structure of Berland army is organized in such a way that every officer, except for the commander, is a subordinate of the commander of the army.

Formally, let's represent Berland army as a tree consisting of 1) corresponds to the commander of the army.

Berland War Ministry has ordered you to give answers on ki is a positive integer.

To process the ui. Typical DFS (depth first search) algorithm is used here.

Suppose the current officer is a finishes spreading the command.

Let's look at the following example:

Codeforces Round #498 (Div. 3) E. Military Problem

If officer [1,2,3,5,6,8,7,9,4].

If officer [3,5,6,8,7,9].

If officer [7,9].

If officer [9].

To answer the ki elements in it.

You should process queries independently. A query doesn't affect the following queries.

Input

The first line of the input contains two integers 2≤n≤2⋅105,1≤q≤2⋅105) — the number of officers in Berland army and the number of queries.

The second line of the input contains 1 and doesn't have any superiors.

The next ki is the index of the required officer in the command spreading sequence.

Output

Print ki.

You should process queries independently. They do not affect each other.

Example
input
Copy
9 6
1 1 1 3 5 3 5 7
3 1
1 5
3 4
7 3
1 8
1 9
output
Copy
3
6
8
-1
9
4
题意:给你n个节点的数和q次查询
节点输入规则是i的父节点是di
查询规则是,求从节点a开始,查询他的子树的第i个节点
题解:先用dfs预处理每一个节点对应的子树的数量和该数量对应的节点个数
代码如下
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;

const int mx = 2e5+10;
vector<int> v[mx];
int vis[mx], sum[mx], cnt = 1, s[mx];
//预处理dfs序
int dfs(int id){
    int ans = 1;
    vis[id] = cnt;  //其子树的数量
    s[cnt] = id;   //对应子树数量对应的节点
    cnt++;
    for (int i = 0; i < v[id].size(); i++){
        ans += dfs(v[id][i]);   //访问节点
    }
    return sum[id] += ans;  //返回子树个数
}

int main(){
    int n, q, p, x, y;
    scanf("%d%d", &n, &q);
    for (int i = 1; i < n; i++){
        scanf("%d", &p);
        v[p].push_back(i+1);//子节点
    }
    dfs(1);
    while (q--){
        scanf("%d%d", &x, &y);
        if (sum[x] < y) printf("-1\n");
        else printf("%d\n", s[vis[x]+y-1]);
    }
    return 0;
}

 



相关文章: