bzoj 2588: Spoj 10628. Count on a tree
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 2588: Spoj 10628. Count on a tree相关的知识,希望对你有一定的参考价值。
DFS序在树上建出主席树,然后。。。。。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #define ll long long 8 #define M 200009 9 using namespace std; 10 ll read() 11 { 12 ll x=0,f=1; 13 char ch=getchar(); 14 for(;ch<‘0‘||ch>‘9‘;ch=getchar()) 15 if(ch==‘-‘) 16 f=-1; 17 for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) 18 x=x*10+ch-‘0‘; 19 return x*f; 20 } 21 int lc[M][20],head[M],next[M],u[M],cnt,n,m,v[M],v1[M],n1,deep[M],pos[M],num[M],T,root[M]; 22 int tot,lastans; 23 struct data 24 { 25 int l,r,sum; 26 }a[20*M]; 27 void jia(int a1,int a2) 28 { 29 next[++cnt]=head[a1]; 30 head[a1]=cnt; 31 u[cnt]=a2; 32 } 33 void dfs(int x) 34 { 35 num[++T]=x; 36 pos[x]=T; 37 for(int i=1;(1<<i)<=deep[x];i++) 38 lc[x][i]=lc[lc[x][i-1]][i-1]; 39 for(int i=head[x];i;i=next[i]) 40 if(u[i]!=lc[x][0]) 41 { 42 deep[u[i]]=deep[x]+1; 43 lc[u[i]][0]=x; 44 dfs(u[i]); 45 } 46 } 47 void geng(int l,int r,int x,int &y,int z) 48 { 49 y=++tot; 50 a[y].sum=a[x].sum+1; 51 if(l==r) 52 return; 53 a[y].l=a[x].l; 54 a[y].r=a[x].r; 55 int mid=(l+r)>>1; 56 if(mid>=z) 57 geng(l,mid,a[x].l,a[y].l,z); 58 else 59 geng(mid+1,r,a[x].r,a[y].r,z); 60 } 61 int lca(int a1,int a2) 62 { 63 if(deep[a1]<deep[a2]) 64 swap(a1,a2); 65 int a3=deep[a1]-deep[a2]; 66 for(int i=0;i<=16;i++) 67 if(a3&(1<<i)) 68 a1=lc[a1][i]; 69 for(int i=16;i>=0;i--) 70 if(lc[a1][i]!=lc[a2][i]) 71 { 72 a1=lc[a1][i]; 73 a2=lc[a2][i]; 74 } 75 if(a1==a2) 76 return a1; 77 return lc[a1][0]; 78 } 79 int cha(int u,int v,int t,int k) 80 { 81 int a1=root[pos[u]],a2=root[pos[v]],a3=root[pos[t]],a4=root[pos[lc[t][0]]]; 82 int l=1,r=n1-1,ans; 83 for(;;) 84 { 85 if(l==r) 86 return v1[l]; 87 int mid=(l+r)>>1; 88 int a5=a[a[a1].l].sum+a[a[a2].l].sum-a[a[a3].l].sum-a[a[a4].l].sum; 89 if(a5>=k) 90 { 91 r=mid; 92 a1=a[a1].l; 93 a2=a[a2].l; 94 a3=a[a3].l; 95 a4=a[a4].l; 96 } 97 else 98 { 99 k-=a5; 100 l=mid+1; 101 a1=a[a1].r; 102 a2=a[a2].r; 103 a3=a[a3].r; 104 a4=a[a4].r; 105 } 106 } 107 } 108 int main() 109 { 110 n=read(); 111 m=read(); 112 for(int i=1;i<=n;i++) 113 v1[i]=v[i]=read(); 114 sort(v1+1,v1+n+1); 115 n1=unique(v1+1,v1+n+1)-v1; 116 for(int i=1;i<=n;i++) 117 v[i]=lower_bound(v1+1,v1+n1,v[i])-v1; 118 for(int i=1;i<n;i++) 119 { 120 int a1=read(),a2=read(); 121 jia(a1,a2); 122 jia(a2,a1); 123 } 124 dfs(1); 125 for(int i=1;i<=n;i++) 126 geng(1,n1-1,root[pos[lc[num[i]][0]]],root[i],v[num[i]]); 127 for(int i=1;i<=m;i++) 128 { 129 int u=read()^lastans,v=read(),k=read(); 130 int t=lca(u,v); 131 printf("%d",lastans=cha(u,v,t,k)); 132 if(i!=m) 133 printf("\n"); 134 } 135 return 0; 136 }
以上是关于bzoj 2588: Spoj 10628. Count on a tree的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]
BZOJ2588 Spoj 10628. Count on a tree
[BZOJ2588][Spoj 10628]Count on a tree
bzoj 2588: Spoj 10628. Count on a tree LCA+主席树