bzoj 1803: Spoj1487 Query on a tree III(主席樹)

題意ios

你被給定一棵帶點權的n個點的有根數,點從1到n編號。git

定義查詢 query(x,k): 尋找以x爲根的k大點的編號(從小到大排序第k個點)spa

假設沒有兩個相同的點權。code

輸入格式: 第一行爲整數n,第二行爲點權,接下來n-1行爲樹邊,接下來一行爲整數m,下面m行爲兩個整數x,k,表明query(x,k)blog

輸出格式: m行,輸出每次查詢的結果。排序

題解get

先一遍dfs,而後建個主席樹,帶上去直接跑一跑就行了it

我忘了注意dfs序的位置和原來的編號……結果調了半天啥都調不出來……io

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<algorithm>
 5 using namespace std;
 6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 7 char buf[1<<21],*p1=buf,*p2=buf;
 8 inline int read(){
 9     #define num ch-'0'
10     char ch;bool flag=0;int res;
11     while(!isdigit(ch=getc()))
12     (ch=='-')&&(flag=true);
13     for(res=num;isdigit(ch=getc());res=res*10+num);
14     (flag)&&(res=-res);
15     #undef num
16     return res;
17 }
18 char obuf[1<<24],*o=obuf;
19 inline void print(int x){
20     if(x>9) print(x/10);
21     *o++=x%10+48;
22 }
23 const int N=100005,M=N*30;
24 int sum[M],L[M],R[M],rt[N];
25 int ver[N<<1],Next[N<<1],head[N];
26 int ls[N],rs[N],a[N],b[N],id[N],pos[N];
27 int n,m,cnt,tot,q;
28 void update(int last,int &now,int l,int r,int x){
29     sum[now=++cnt]=sum[last]+1;
30     if(l==r) return;
31     int mid=(l+r)>>1;
32     if(x<=mid) R[now]=R[last],update(L[last],L[now],l,mid,x);
33     else L[now]=L[last],update(R[last],R[now],mid+1,r,x);
34 }
35 int query(int u,int v,int l,int r,int k){
36     if(l>=r) return l;
37     int x=sum[L[v]]-sum[L[u]];
38     int mid=(l+r)>>1;
39     if(x>=k) return query(L[u],L[v],l,mid,k);
40     else return query(R[u],R[v],mid+1,r,k-x);
41 }
42 inline void add(int u,int v){
43     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
44     ver[++tot]=u,Next[tot]=head[v],head[v]=tot;
45 }
46 void dfs(int u,int fa){
47     a[ls[u]=++m]=b[u],id[m]=u;
48     for(int i=head[u];i;i=Next[i])
49     if(ver[i]!=fa) dfs(ver[i],u);
50     rs[u]=m;
51 }
52 int main(){
53     //freopen("testdata.in","r",stdin);
54     n=read();
55     for(int i=1;i<=n;++i) b[i]=read();
56     for(int i=1;i<n;++i){
57         int u,v;
58         u=read(),v=read();
59         add(u,v);
60     }
61     dfs(1,0);
62     sort(b+1,b+1+m);
63     for(int i=1;i<=n;++i){
64         int k=lower_bound(b+1,b+1+m,a[i])-b;
65         update(rt[i-1],rt[i],1,m,k);
66         pos[k]=id[i];
67     }
68     q=read();
69     while(q--){
70         int u=read(),k=read();
71         int ans=pos[query(rt[ls[u]-1],rt[rs[u]],1,m,k)];
72         print(ans),*o++='\n';
73     }
74     fwrite(obuf,o-obuf,1,stdout);
75     return 0;
76 }
相關文章
相關標籤/搜索