BZOJ2588 [SPOJ10628]Count on a tree

Description

给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。

 

Input

第一行两个整数N,M。
第二行有N个整数,其中第i个整数表示点i的权值。
后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
最后M行每行两个整数(u,v,k),表示一组询问。

Output

M行,表示每个询问的答案。最后一个询问不输出换行符

Sample Input

8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2

Sample Output

2
8
9
105
7

HINT

N,M<=100000

 

正解:主席树
 
解题报告:感觉主席树不是很熟练,想练一练,就打一道练练手,今天竟然一次打对AC,当然第一次的PE不算在里面。
 
  1 #include <iostream>
  2 #include <iomanip>
  3 #include <cstdlib>
  4 #include <cstdio>
  5 #include <cstring>
  6 #include <cmath>
  7 #include <algorithm>
  8 #include <string>
  9 #define RG register
 10 const int N = 3000000;
 11 const int M = 300000;
 12 
 13 using namespace std;
 14 
 15 int siz[M],nn[M*2][2],head[M],ra[M],fa[M],id[M],son[M];
 16 int cnt,dis[M],top[M],n,m,a[N],b[N],rt[M],sa[M],w[M],ans;
 17 
 18 struct date{
 19     int s,i;
 20     bool operator < (const date a) const{
 21         return s<a.s;
 22     }
 23 }f[M];
 24 
 25 int gi(){
 26     char ch=getchar();int x=0;
 27     while(ch<'0' || ch>'9') ch=getchar();
 28     while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
 29     return x;
 30 }
 31 
 32 void dfs1(int xh,int fu){
 33     fa[xh]=fu,dis[xh]=dis[fu]+1;
 34     for (RG int i=head[xh]; i; i=nn[i][0]){
 35         if (nn[i][1]==fu) continue;
 36         dfs1(nn[i][1],xh);
 37         siz[xh]+=siz[nn[i][1]];
 38         if (siz[nn[i][1]]>siz[son[xh]])
 39             son[xh]=nn[i][1];
 40     }
 41     ++siz[xh];
 42     return;
 43 }
 44 
 45 struct dota{
 46     int s,l,r;
 47 }tr[N];
 48 
 49 void build(int x,int &t,int l,int r){
 50     tr[++ans]=tr[t];t=ans;
 51     ++tr[ans].s;
 52     if (l==r) return;
 53     int mid=(l+r)>>1;
 54     if (x<=mid) build(x,tr[ans].l,l,mid);
 55     else build(x,tr[ans].r,mid+1,r);
 56     return;
 57 }
 58 
 59 void dfs2(int xh,int tp){
 60     id[xh]=++cnt,top[xh]=tp;
 61     rt[cnt]=rt[cnt-1],build(ra[xh],rt[cnt],1,n);
 62     if (son[xh]) dfs2(son[xh],tp);
 63     for (RG int i=head[xh]; i; i=nn[i][0]){
 64         if (nn[i][1]==son[xh] || nn[i][1]==fa[xh]) continue;
 65         dfs2(nn[i][1],nn[i][1]);
 66     }
 67     return;
 68 }
 69 
 70 int query(int l,int r,int k){
 71     RG int tot=0;
 72     while(top[l]!=top[r])
 73         if (dis[top[l]]>dis[top[r]]) a[++tot]=rt[id[top[l]]-1],b[tot]=rt[id[l]],l=fa[top[l]];
 74         else a[++tot]=rt[id[top[r]]-1],b[tot]=rt[id[r]],r=fa[top[r]];
 75     if (dis[l]>dis[r]) a[++tot]=rt[id[r]-1],b[tot]=rt[id[l]];
 76     else a[++tot]=rt[id[l]-1],b[tot]=rt[id[r]];
 77     RG int z=1,y=n,mid;
 78     while(z!=y){
 79         RG int a1=0,b1=0;
 80         mid=(z+y)>>1;
 81         for (RG int i=1; i<=tot; ++i) a1+=tr[tr[a[i]].l].s;
 82         for (RG int i=1; i<=tot; ++i) b1+=tr[tr[b[i]].l].s;
 83         if (b1-a1>=k){
 84             for (RG int i=1; i<=tot; ++i) a[i]=tr[a[i]].l;
 85             for (RG int i=1; i<=tot; ++i) b[i]=tr[b[i]].l;
 86             y=mid;
 87         }
 88         else{
 89             for (RG int i=1; i<=tot; ++i) a[i]=tr[a[i]].r;
 90             for (RG int i=1; i<=tot; ++i) b[i]=tr[b[i]].r;
 91             z=mid+1,k-=(b1-a1);
 92         }
 93     }
 94     return z;
 95 }
 96 
 97 int main(){
 98     n=gi(),m=gi();
 99     for (RG int i=1; i<=n; ++i) f[i]=(date){gi(),i},w[i]=f[i].s;
100     sort(f+1,f+n+1);
101     for (RG int i=1; i<=n; ++i) ra[f[i].i]=i,sa[i]=f[i].i;
102     for (RG int i=1; i<n;  ++i){
103         RG int l=gi(),r=gi();
104         nn[++cnt][1]=l,nn[cnt][0]=head[r],head[r]=cnt;
105         nn[++cnt][1]=r,nn[cnt][0]=head[l],head[l]=cnt;
106     }
107     cnt=0;
108     dfs1(1,0),dfs2(1,1);
109     int jl=0;
110     for (RG int i=1; i<m; ++i){
111         RG int l=gi()^jl,r=gi(),k=gi();
112         jl=query(l,r,k);
113         printf("%d\n",w[sa[jl]]);
114         jl=w[sa[jl]];
115     }
116     RG int l=gi()^jl,r=gi(),k=gi();
117     jl=query(l,r,k);
118     printf("%d",w[sa[jl]]);
119     jl=w[sa[jl]];
120     return 0;
121 }

 

posted @ 2017-02-28 11:30  Cjk_2001  阅读(156)  评论(0编辑  收藏  举报