其他分享
首页 > 其他分享> > Luogu P2633 Count on a tree

Luogu P2633 Count on a tree

作者:互联网

题目链接:https://www.luogu.com.cn/problem/P2633

 

 

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=200011,K=N<<5,G=31;
  4 int n,m,a[N],b[N],num;
  5 int to[N],nxt[N],edge,head[N];
  6 int gr[N][G],dep[N];
  7 int cnt[K],ch[K][2],tot,rt[N];
  8 
  9 inline int re_ad() {
 10     char ch=getchar(); int x=0,f=1;
 11     while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
 12     while('0'<=ch && ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
 13     return x*f;
 14 }
 15 
 16 inline void addedge(int x,int y) {
 17     ++edge,to[edge]=y,nxt[edge]=head[x],head[x]=edge;
 18     ++edge,to[edge]=x,nxt[edge]=head[y],head[y]=edge;
 19 }
 20 
 21 inline void pushup(int d) {
 22     cnt[d]=cnt[ch[d][0]]+cnt[ch[d][1]];
 23 }
 24 
 25 int build(int l,int r) {
 26     int d=++tot;
 27     if(l==r) return d;
 28     int mid=(l+r)>>1;
 29     ch[d][0]=build(l,mid);
 30     ch[d][1]=build(mid+1,r);
 31     return d;
 32 }
 33 
 34 int update(int p,int l,int r,int k) {
 35     int d=++tot;
 36     if(l==r) {
 37         cnt[d]=cnt[p]+1;
 38         return d;
 39     }
 40     int mid=(l+r)>>1;
 41     ch[d][0]=ch[p][0],ch[d][1]=ch[p][1];
 42     if(k<=mid) ch[d][0]=update(ch[p][0],l,mid,k);
 43     else ch[d][1]=update(ch[p][1],mid+1,r,k);
 44     pushup(d);
 45     return d;
 46 }
 47 
 48 int query(int d1,int d2,int p1,int p2,int l,int r,int k) {
 49     if(l==r) return l;
 50     int cur=cnt[ch[d1][0]]+cnt[ch[d2][0]]-cnt[ch[p1][0]]-cnt[ch[p2][0]];
 51     int mid=(l+r)>>1;
 52     if(cur>=k) return query(ch[d1][0],ch[d2][0],ch[p1][0],ch[p2][0],l,mid,k);
 53     else return query(ch[d1][1],ch[d2][1],ch[p1][1],ch[p2][1],mid+1,r,k-cur);
 54 }
 55 
 56 void dfs(int d,int f) {
 57     gr[d][0]=f,dep[d]=dep[f]+1;
 58     for(int i=1;i<=20;++i) gr[d][i]=gr[gr[d][i-1]][i-1];
 59     rt[d]=update(rt[f],1,num,a[d]);
 60     for(int i=head[d],u;i;i=nxt[i]) {
 61         u=to[i];
 62         if(u==f) continue;
 63         dfs(u,d);
 64     }
 65 }
 66 
 67 inline int LCA(int x,int y) {
 68     int fx,fy;
 69     if(dep[x]<dep[y]) x^=y^=x^=y;
 70     for(int i=20;i>=0;--i) {
 71         fx=gr[x][i];
 72         if(dep[fx]>=dep[y]) x=fx;
 73     }
 74     if(x==y) return x;
 75     for(int i=20;i>=0;--i) {
 76         fx=gr[x][i],fy=gr[y][i];
 77         if(fx!=fy) x=fx,y=fy;
 78     }
 79     return gr[x][0];
 80 }
 81 
 82 int main()
 83 {
 84 //    freopen("P2633_1.in","r",stdin);
 85     int x,y,z,tmp;
 86     n=re_ad(),m=re_ad();
 87     for(int i=1;i<=n;++i) b[i]=a[i]=re_ad();
 88     sort(b+1,b+n+1);
 89     num=unique(b+1,b+n+1)-b-1;
 90     for(int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+num+1,a[i])-b;
 91     for(int i=1;i<=n-1;++i) x=re_ad(),y=re_ad(),addedge(x,y);
 92     rt[0]=build(1,num);
 93     dfs(1,0);
 94     int lst=0,lca,lcafa;
 95 //    for(int i=1;i<=n*2;++i) printf("%d ",cnt[i]); puts("");
 96     for(int i=1;i<=m;++i) {
 97         x=re_ad(),y=re_ad(),z=re_ad();
 98 //        printf("%d %d %d %d\n",x,y,lst,x^lst);
 99         x^=lst;
100 //        printf("%d %d %d %d\n",x,y,lca,lcafa);
101         lca=LCA(x,y),lcafa=gr[lca][0];
102         tmp=query(rt[x],rt[y],rt[lca],rt[lcafa],1,num,z);
103         printf("%d\n",b[tmp]);
104         lst=b[tmp];
105     }
106     return 0;
107 }

 

标签:Count,ch,return,gr,int,Luogu,tree,mid,fx
来源: https://www.cnblogs.com/shangguanshufang/p/Luogu_P2633_Count_on_a_tree.html