题目
1<=n<=1e5,1<=m<=1e4;
输入样例#1:
5
1 3 5 2 7
1 2
2 3
1 4
3 5
4
2 3
4 1
3 2
3 2
输出样例#1:
5
4
5
5
题解:这个题输出子树第K小这个值对应原数列的哪一个 也就是可通过主席树+dfs序求出ai,但是要输出i。
因为要离散化。1-n数组 预处理一下id[dex]=i,dex是指离散化后的“权值”。
平常输出ai是则输出refl[query()],这里输出id[query()]。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
struct Edge{int to,nex;}edge[N<<1];int head[N],tot;
void add(int from,int to){
edge[++tot]=(Edge){to,head[from]},head[from]=tot;
}
struct tree{int l,r,sum;}t[N*20];
int root[N],sz;
void update(int pos,int& x,int y,int l,int r){
t[x=++sz]=t[y],++t[x].sum;
if(l==r) return;
int mid=(l+r)>>1;
if(pos<=mid) update(pos,t[x].l,t[y].l,l,mid);
else update(pos,t[x].r,t[y].r,mid+1,r);
}
int query(int K,int x,int y,int l,int r){
if(l==r) return l;
int mid=(l+r)>>1,left=t[t[y].l].sum-t[t[x].l].sum;
if(K<=left) return query(K,t[x].l,t[y].l,l,mid);
return query(K-left,t[x].r,t[y].r,mid+1,r);
}
int in[N],out[N],fp[N],n;
void dfs(int x){
in[x]=n++,fp[n-1]=x;
for(int i=head[x];i;i=edge[i].nex) dfs(edge[i].to);
out[x]=n-1;
}
int a[N],val[N],refl[N],id[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]),refl[i]=a[i];
sort(refl+1,refl+n+1);
int tot=unique(refl+1,refl+n+1)-(refl+1);
for(int i=1,x,y;i<n;++i) scanf("%d%d",&x,&y),add(x,y);
n=1,dfs(1),--n;
for(int i=1;i<=n;++i) id[lower_bound(refl+1,refl+tot+1,a[i])-refl]=i;
for(int i=1;i<=n;++i){
int dex=lower_bound(refl+1,refl+tot+1,a[fp[i]])-refl;
update(dex,root[i],root[i-1],1,tot);
}
int q;scanf("%d",&q);
while(q--){
int x,K;scanf("%d%d",&x,&K);
printf("%d\n",id[query(K,root[in[x]-1],root[out[x]],1,tot)]);
}
}