Military Problem
题目地址:
基本思路:
题目很长,可以概况为给你一棵树,每次查询,
你要找到从开始按照遍历顺序,遍历到的第个节点,
也就是找到点对应序后第个的节点就是了,
然后注意超出子树的范围了要输出。
参考代码:
#include <bits/stdc++.h> using namespace std; #define IO std::ios::sync_with_stdio(false); cin.tie(0) #define ll long long #define ull unsigned long long #define SZ(x) ((int)(x).size()) #define all(x) (x).begin(), (x).end() #define rep(i, l, r) for (int i = l; i <= r; i++) #define per(i, l, r) for (int i = l; i >= r; i--) #define mset(s, _) memset(s, _, sizeof(s)) #define pb push_back #define pii pair <int, int> #define mp(a, b) make_pair(a, b) #define debug(x) cerr << #x << " = " << x << '\n'; #define pll pair <ll, ll> #define fir first #define sec second #define INF 0x3f3f3f3f inline int read() { int x = 0, neg = 1; char op = getchar(); while (!isdigit(op)) { if (op == '-') neg = -1; op = getchar(); } while (isdigit(op)) { x = 10 * x + op - '0'; op = getchar(); } return neg * x; } inline void print(int x) { if (x < 0) { putchar('-'); x = -x; } if (x >= 10) print(x / 10); putchar(x % 10 + '0'); } const int maxn = 2e5 + 10; int n,m; vector<int> G[maxn]; int dfn[maxn],id[maxn],mx[maxn]; signed main() { n = read(),m = read(); rep(i,2,n){ int p = read(); G[i].push_back(p); G[p].push_back(i); } int tot = 0; function<void(int,int)> dfs = [&](int u,int par){ dfn[u] = ++tot; id[tot] = u; for(auto to : G[u]){ if(to == par) continue; dfs(to,u); } mx[u] = tot; }; dfs(1,0); for(int i = 1 ; i <= m ; i++){ int u = read(),k = read(); int now = dfn[u] + k - 1; int res = -1; if(now <= mx[u]) res = id[now]; print(res); puts(""); } return 0; }