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