[BZOJ1803]Spoj1487 Query on a tree III(dfs序+主席树)

来源:互联网 发布:swot矩阵分析图 绘制 编辑:程序博客网 时间:2024/06/06 00:31

题目描述

传送门

题解

裸dfs序+主席树。

代码

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define N 100005int n,m,x,y,k,ans,a[N],b[N],mp[N];int tot,point[N],nxt[N*2],v[N*2];int in[N],out[N],dfs_clock,root[N],sz,pt[N];int sum[N*30],ls[N*30],rs[N*30];int find(int x){    int l=1,r=n,mid,ans;    while (l<=r)    {        mid=(l+r)>>1;        if (b[mid]<=x) ans=mid,l=mid+1;        else r=mid-1;    }    return ans;}void add(int x,int y){    ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;}void dfs(int x,int fa){    in[x]=++dfs_clock;pt[dfs_clock]=x;    for (int i=point[x];i;i=nxt[i])        if (v[i]!=fa)            dfs(v[i],x);    out[x]=dfs_clock;}void update(int &now,int l,int r,int w){    int mid=(l+r)>>1;    sum[++sz]=sum[now]+1,ls[sz]=ls[now],rs[sz]=rs[now];    now=sz;    if (l==r) return;    if (w<=mid) update(ls[now],l,mid,w);    else update(rs[now],mid+1,r,w);}int query(int l,int r,int rl,int rr,int k){    int mid=(l+r)>>1;    if (l==r) return l;    int t=sum[ls[rr]]-sum[ls[rl]];    if (t>=k) return query(l,mid,ls[rl],ls[rr],k);    else query(mid+1,r,rs[rl],rs[rr],k-t);}int main(){    scanf("%d",&n);    for (int i=1;i<=n;++i)        scanf("%d",&a[i]),b[i]=a[i];    sort(b+1,b+n+1);    for (int i=1;i<=n;++i)        x=find(a[i]),mp[x]=i,a[i]=x;    for (int i=1;i<n;++i)    {        scanf("%d%d",&x,&y);        add(x,y);add(y,x);    }    dfs(1,0);    for (int i=1;i<=n;++i)    {        x=pt[i];        root[i]=root[i-1];        update(root[i],1,n,a[x]);    }    scanf("%d",&m);    for (int i=1;i<=m;++i)    {        scanf("%d%d",&x,&k);        int l=in[x],r=out[x],L,R;        ans=mp[query(1,n,root[l-1],root[r],k)];        printf("%d\n",ans);    }}
0 0