COJ 1011 WZJ的数据结构(十一)树上k大

题解:主席树&DFS序。

PS:为什么我一开始Wa了N发 是因为有一个左区间我写成[L,M+1]了。。。。。。。。。。。。。。。。。。。。。。。。。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cstring>
 7 #define PAU putchar(' ')
 8 #define ENT putchar('\n')
 9 using namespace std;
10 const int maxn=100000+10,maxnode=20000000+10,maxn2=200000+10;
11 int ls[maxnode],rs[maxnode],s[maxnode],A[maxn],root[maxn],p[maxn],si[maxn],so[maxn],siz[maxn],cz=0,tot=0;
12 struct tedge{int x,y,next;}adj[maxn2];int ms=0,fch[maxn];
13 void addedge(int u,int v){
14     adj[++ms]=(tedge){u,v,fch[u]};fch[u]=ms;
15     adj[++ms]=(tedge){v,u,fch[v]};fch[v]=ms;
16     return;
17 }
18 void build(int x,int&y,int L,int R,int pos){
19     s[y=++tot]=s[x]+1;if(L==R) return;
20     int M=L+R>>1;21     if(pos<=M) rs[y]=rs[x],build(ls[x],ls[y],L,M,pos);
22     else ls[y]=ls[x],build(rs[x],rs[y],M+1,R,pos);
23 }
24 int query(int x,int y,int L,int R,int k){
25     if(L==R) return L;int M=L+R>>1,kth=s[ls[y]]-s[ls[x]];
26     if(k<=kth) return query(ls[x],ls[y],L,M,k);
27     else return query(rs[x],rs[y],M+1,R,k-kth);
28 }
29 void dfs(int u,int fa){
30     si[u]=++cz;p[cz]=u;siz[u]=1;
31     for(int i=fch[u];i;i=adj[i].next){
32         int v=adj[i].y;
33         if(v!=fa) dfs(v,u),siz[u]+=siz[v];
34     } so[u]=cz;return;
35 }
36 inline int read(){
37     int x=0,sig=1;char ch=getchar();
38     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
39     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
40     return x*=sig;
41 }
42 inline void write(int x){
43     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
44     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
45     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
46 }
47 int n,Q;
48 void init(){
49     n=read();Q=read();
50     for(int i=1;i<n;i++) addedge(read(),read());
51     for(int i=1;i<=n;i++) A[i]=read();
52     dfs(1,0);
53     for(int i=1;i<=n;i++) build(root[i-1],root[i],1,n,A[p[i]]);
54     return;
55 }
56 void work(){
57     int x,k;
58     while(Q--){
59         x=read();k=read();
60         if(siz[x]<k) puts("-1");
61         else write(query(root[si[x]-1],root[so[x]],1,n,k)),ENT;
62     }
63     return;
64 }
65 void print(){
66     return;
67 }
68 int main(){init();work();print();return 0;}

 

你可能感兴趣的:(数据结构)