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;}