洛谷 2633 BZOJ 2588 Spoj 10628. Count on a tree
【题解】
蜜汁强制在线。。。
每个点开一个从它到根的可持久化权值线段树。查询的时候利用差分的思想在树上左右横跳就好了。
1 #include<cstdio> 2 #include<algorithm> 3 #define N 100010 4 #define rg register 5 #define ls (a[u].l) 6 #define rs (a[u].r) 7 using namespace std; 8 int n,n2,m,tot,root[N],last[N],dep[N],top[N],hvy[N],fa[N],size[N],val[N],b[N]; 9 struct tree{ 10 int sum,l,r; 11 }a[N*80]; 12 struct edge{ 13 int to,pre; 14 }e[N<<1]; 15 inline int read(){ 16 int k=0,f=1; char c=getchar(); 17 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 18 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 19 return k*f; 20 } 21 inline int qlca(int x,int y){ 22 int f1=top[x],f2=top[y]; 23 while(f1!=f2){ 24 if(dep[f1]<dep[f2]) swap(x,y),swap(f1,f2); 25 x=fa[f1]; f1=top[x]; 26 } 27 return dep[x]<dep[y]?x:y; 28 } 29 void update(int &u,int l,int r,int pos){ 30 a[++tot]=a[u]; a[u=tot].sum++; 31 if(l==r) return; 32 int mid=(l+r)>>1; 33 if(pos<=mid) update(ls,l,mid,pos); 34 else update(rs,mid+1,r,pos); 35 } 36 int query(int u,int v,int lca,int f,int l,int r,int k){ 37 if(l==r) return l; 38 int tmp=a[ls].sum+a[a[v].l].sum-a[a[lca].l].sum-a[a[f].l].sum,mid=(l+r)>>1; 39 return k<=tmp?query(ls,a[v].l,a[lca].l,a[f].l,l,mid,k):query(rs,a[v].r,a[lca].r,a[f].r,mid+1,r,k-tmp); 40 } 41 void dfs1(int x){ 42 size[x]=1; dep[x]=dep[fa[x]]+1; 43 root[x]=root[fa[x]]; update(root[x],1,n2,val[x]); 44 for(rg int i=last[x],to;i;i=e[i].pre)if((to=e[i].to)!=fa[x]){ 45 fa[to]=x; dfs1(to); 46 size[x]+=size[to]; 47 if(size[to]>size[hvy[x]]) hvy[x]=to; 48 } 49 } 50 void dfs2(int x,int tp){ 51 top[x]=tp; 52 if(hvy[x]) dfs2(hvy[x],tp); 53 for(rg int i=last[x],to;i;i=e[i].pre) 54 if((to=e[i].to)!=fa[x]&&to!=hvy[x]) dfs2(to,to); 55 } 56 int main(){ 57 n=read(); m=read(); 58 for(rg int i=1;i<=n;i++) val[i]=b[i]=read(); 59 sort(b+1,b+1+n); n2=unique(b+1,b+1+n)-b-1; 60 for(rg int i=1;i<=n;i++) val[i]=lower_bound(b+1,b+1+n2,val[i])-b; 61 for(rg int i=1;i<n;i++){ 62 int u=read(),v=read(); 63 e[++tot]=(edge){v,last[u]}; last[u]=tot; 64 e[++tot]=(edge){u,last[v]}; last[v]=tot; 65 } 66 tot=0; dfs1(1); dfs2(1,1); 67 int last=0; 68 while(m--){ 69 int u=read()^last,v=read(),k=read(),l=qlca(u,v),f=fa[l]; 70 printf("%d\n",last=b[query(root[u],root[v],root[l],root[f],1,n2,k)]); 71 } 72 return 0; 73 }