[LUOGU]P2633 Count on a tree

其实和luogu上主席树的板子差不多,就是把它放到了树上,把板子改成求sum[u]+sum[v]-sum[lca]-sum[lcafa]的就行了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=100005;
struct Edge{int to,nxt;}e[N<<1];
int tim,dfn1[N],dfn2[N],top[N],son[N],siz[N],fa[N],dep[N],head[N],ecnt,rt[N<<5],a[N],b[N],u,n,m;
void add(int bg,int ed) {e[++ecnt].nxt=head[bg];e[ecnt].to=ed;head[bg]=ecnt;}
void dfs(int x) {
	siz[x]=1;
	for(int i=head[x];i;i=e[i].nxt) {
		int v=e[i].to;
		if(v==fa[x]) continue;
		fa[v]=x,dep[v]=dep[x]+1;
		dfs(v);siz[x]+=siz[v];
		if(siz[v]>siz[son[x]]) son[x]=v;
	}
}
void dfs(int x,int qtop) {
	top[x]=qtop;dfn1[x]=++tim;
	if(!son[x]) return;
	dfs(son[x],qtop);
	for(int i=head[x];i;i=e[i].nxt) {
		int v=e[i].to;
		if(v==son[x]||v==fa[x]) continue;
		dfs(v,v);
	}
	dfn2[x]=tim;
}
int ls[N<<5],rs[N<<5],sum[N<<5],tot;
void build(int &k,int l,int r) {
	k=++tot;
	if(l<r) {
		int mid=l+r>>1;
		build(ls[k],l,mid);
		build(rs[k],mid+1,r);
	}
}
void update(int &k,int l,int r,int pre,int c) {
	ls[k=++tot]=ls[pre],rs[k]=rs[pre],sum[k]=sum[pre]+1;
	if(l<r) {
		int mid=l+r>>1;
		if(c<=mid) update(ls[k],l,mid,ls[pre],c);
		else update(rs[k],mid+1,r,rs[pre],c);
	}
}
int query(int u,int v,int lca,int lcafa,int l,int r,int kth) {
	if(l==r) return l;
	int nowsiz=sum[ls[u]]+sum[ls[v]]-sum[ls[lca]]-sum[ls[lcafa]],mid=l+r>>1;
	if(nowsiz<kth) return query(rs[u],rs[v],rs[lca],rs[lcafa],mid+1,r,kth-nowsiz);
	return query(ls[u],ls[v],ls[lca],ls[lcafa],l,mid,kth);
}
void chairman(int x) {
	update(rt[x],1,u,rt[fa[x]],a[x]);
	for(int i=head[x];i;i=e[i].nxt) {
		int v=e[i].to;
		if(v!=fa[x]) chairman(v);
	}
}
int LCA(int x,int y) {
	while(top[x]!=top[y]) 
		(dep[top[x]]>=dep[top[y]])?x=fa[top[x]]:y=fa[top[y]];
	return dep[x]<dep[y]?x:y;
}
int lastans;
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
	for(int i=1,x,y;i<n;i++) {
		scanf("%d%d",&x,&y);
		add(x,y);add(y,x);
	}
	sort(b+1,b+1+n);
	u=unique(b+1,b+1+n)-b-1;
	for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+u,a[i])-b;
	build(rt[0],1,u);
	dfs(1);dfs(1,1);
	chairman(1);
	int lca,xx,v,k;
	while(m--) {
		scanf("%d%d%d",&xx,&v,&k);
		xx^=lastans;
		lca=LCA(xx,v);
		printf("%d\n",lastans=b[query(rt[xx],rt[v],rt[lca],rt[fa[lca]],1,u,k)]);
	}
}
posted @ 2018-08-15 20:27  SWHsz  阅读(113)  评论(0编辑  收藏  举报