靠又别水题虐了。。。
题目还是比较基础的
就是直接树上k大就可以了
首先一次dfs得到dfs序
然后建立主席树
接下来询问的时候
因为dfs序每个节点出现过两次
所以k大的k要乘2
然后直接两个线段树减一下就可以了
总体来说还是挺简单的。。。
但是我还是进了主席树的大坑
就是空间问题。。。
调了好久才刚刚不MLE了。。。大家注意啊。。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define rep(i,j,k) for(int i = j; i <= k; i++)
#define MAX 200009
#define u 18
using namespace std;
int to[1 * MAX], next[1 * MAX], head[1 * MAX], a[MAX], c[MAX];
int n, m, k, dfn[MAX * 1], tree[u * MAX], child[u * MAX][2], size[u * MAX];
int tot = 0, DfsClock = 0, sum = 0, first[MAX * 1], last[1 * MAX], num = 0;
inline void add (int x, int y)
{
to[++tot] = y;
next[tot] = head[x];
head[x] = tot;
}
void dfs (int x, int fa)
{
dfn[first[x] = ++DfsClock] = x;
for (int i = head[x]; i; i = next[i])
if (to[i] != fa)
dfs (to[i], x);
dfn[last[x] = ++DfsClock] = x;
}
inline int add (int l, int r, int pos, int root)
{
int New = ++sum, mid = (l + r) >> 1;
size[New] = size[root] + 1;
if (l == r)
return New;
if (pos <= mid)
child[New][0] = add (l, mid, pos, child[root][0]), child[New][1] = child[root][1];
else
child[New][0] = child[root][0], child[New][1] = add (mid + 1, r, pos, child[root][1]);
return New;
}
struct wbysr
{
int value, id;
}e[MAX];
bool cmp (wbysr a1, wbysr a2)
{
return a1.value < a2.value;
}
int main()
{
scanf ("%d", &n);
rep (i, 1, n)
scanf ("%d", &a[i]), e[i].value = a[i], e[i].id = i;
sort (e + 1, e + 1 + n, cmp);
e[0].value = e[1].value - 90;
rep (i, 1, n)
if (e[i].value != e[i-1].value)
c[++num] = e[i].value;
rep (i, 1, n - 1)
{
int a1, a2;
scanf ("%d%d", &a1, &a2);
add (a1, a2);
add (a2, a1);
}
dfs (1,0);
tree[0] = 0;
size[0] = 0;
rep (i, 1, DfsClock)
tree[i] = add (1, num, lower_bound (c + 1, c + 1 + num, a[dfn[i]]) - c, tree[i - 1]);
scanf ("%d", &m);
while (m--)
{
int x;
scanf ("%d%d", &x, &k);
k *= 2;
int t0 = tree[first[x] - 1], t1 = tree[last[x]];
int l = 1, r = num;
while (l <= r)
{
int now = size[child[t1][0]] - size[child[t0][0]];
int mid = (l + r) >> 1;
if (k <= now)
t0 = child[t0][0], t1 = child[t1][0], r = mid;
else
t0 = child[t0][1], t1 = child[t1][1], k -= now, l = mid + 1;
}
printf ("%d\n", e[r].id);
}
return 0;
}