[xdoj1216]子树第k小(dfs序+主席树)
解题关键:dfs序将树映射到区间,然后主席树求区间第k小,为模板题。
1 #pragma comment(linker, "/STACK:1024000000,1024000000") ` 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cstring> 6 #include<iostream> 7 #include<cmath> 8 #include<vector> 9 typedef long long ll; 10 using namespace std; 11 const int maxn=1e5+4; 12 int head[maxn],in[maxn],out[maxn],cnt,num; 13 int b[maxn],va[maxn]; 14 int n,m; 15 struct Edge{ 16 int to,nxt; 17 }e[maxn<<2]; 18 int root[maxn]; 19 struct node{ 20 int l,r,sum; 21 }p[maxn*22]; 22 23 inline int read(){ 24 char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar()); 25 int x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=(x<<3)+(x<<1)+ls-'0'; 26 if(k=='-')x=0-x;return x; 27 } 28 29 void add_edge(int u,int v){ 30 e[cnt].to=v; 31 e[cnt].nxt=head[u]; 32 head[u]=cnt++; 33 } 34 35 void dfs(int u,int fa){ 36 num++; 37 b[num]=va[u]; 38 in[u]=num; 39 for(int i=head[u];i!=-1;i=e[i].nxt){ 40 int v=e[i].to; 41 if(v==fa) continue; 42 dfs(v,u); 43 } 44 out[u]=num; 45 } 46 47 int build(int l,int r){ 48 int rt=++cnt; 49 p[rt].sum=0; 50 p[rt].l=p[rt].r=0; 51 if(l==r) return rt; 52 int mid=(l+r)>>1; 53 p[rt].l=build(l,mid); 54 p[rt].r=build(mid+1,r); 55 return rt; 56 } 57 58 int update(int l,int r,int c,int k){ 59 int nc=++cnt; 60 p[nc]=p[c]; 61 p[nc].sum++; 62 int mid=(l+r)>>1; 63 if(l==r) return nc; 64 if(mid>=k) p[nc].l=update(l,mid,p[c].l,k); 65 else p[nc].r=update(mid+1,r,p[c].r,k); 66 return nc; 67 } 68 69 int query(int l,int r,int x,int y,int k){ 70 if(l==r) return l; 71 int mid=(l+r)>>1; 72 int sum=p[p[y].l].sum-p[p[x].l].sum; 73 if(sum>=k) return query(l,mid,p[x].l,p[y].l,k); 74 else return query(mid+1,r,p[x].r,p[y].r,k-sum); 75 } 76 vector<int>v; 77 int getid(int x){ 78 return int(lower_bound(v.begin(),v.end(),x)-v.begin())+1; 79 } 80 81 int main(){ 82 while(scanf("%d",&n)!=EOF){ 83 v.clear(); 84 memset(head,-1,sizeof head); 85 cnt=0; 86 num=0; 87 for(int i=1;i<=n;i++) va[i]=read(); 88 for(int i=0;i<n-1;i++){ 89 int t1,t2; 90 t1=read(); 91 t2=read(); 92 add_edge(t1,t2); 93 add_edge(t2,t1); 94 } 95 dfs(1,-1); 96 for(int i=1;i<=n;i++) v.push_back(b[i]); 97 sort(v.begin(),v.end()); 98 v.erase(unique(v.begin(), v.end()),v.end()); 99 root[0]=build(1,n); 100 for(int i=1;i<=n;i++) root[i]=update(1,n,root[i-1],getid(b[i])); 101 int c,d; 102 m=read(); 103 for(int i=0;i<m;i++){ 104 c=read(); 105 d=read(); 106 int ans=query(1,n,root[in[c]-1],root[out[c]],d); 107 printf("%d\n",v[ans-1]); 108 } 109 } 110 return 0; 111 }