洛谷 P2633 Count on a tree 题解

题面

对于每个点建立一颗主席树;

然后按照树上差分的思想统计主席树的前缀和;

lca+主席树+前向星存表就可以了;

#include <bits/stdc++.h>
#define inc(i,a,b) for(register int i=a;i<=b;i++)
#define dec(i,a,b) for(register int i=a;i>=b;i--)
using namespace std;
int head[2000010],cnt;
class littlestar{
	public:
		int to;
		int nxt;
		
}star[2000010];
void add(int u,int v){
	star[++cnt].to=v;
	star[cnt].nxt=head[u];
	head[u]=cnt;
}
int n,m;
template<class nT>
inline void read(nT& x)
{
	char c;
	while(c=getchar(),!isdigit(c));
	x=c^48;
	while(c=getchar(),isdigit(c)) x=x*10+c-48;
}
int a[2000010],val[2000010];
int dep[2000010],f[1000010][30];
void pre(int u,int fa)
{
	//printf("%d %d
",u,fa);
	dep[u]=dep[fa]+1;
	inc(i,0,20){
		f[u][i+1]=f[f[u][i]][i];
	}
	for(register int i=head[u];i;i=star[i].nxt){
		int v=star[i].to;
		if(v==fa) continue;
		f[v][0]=u;
		pre(v,u);
	}
}
int lca(int x,int y)
{
	if(dep[x]<dep[y]) swap(x,y);
	dec(i,19,0){
		if(dep[f[x][i]]>=dep[y]) x=f[x][i];
		if(x==y) return x;
	}
	dec(i,19,0){
		if(f[x][i]!=f[y][i]){
			x=f[x][i];
			y=f[y][i];
		}
	}
	return f[x][0];
}
int rt[20000010];
int num=0;	
class node2{
	public:
 		int l;
 		int r;
 		int w;
}tree[20000010];
void insert(int preroot,int &root,int l,int r,int goal){
	tree[root=++num]=tree[preroot];
	tree[root].w++;
	if(l==r) return;
	int mid=(l+r)>>1;
	if(goal<=mid){
		insert(tree[preroot].l,tree[root].l,l,mid,goal);
	}
	else{
		insert(tree[preroot].r,tree[root].r,mid+1,r,goal);
	}
	tree[root].w=(tree[tree[root].l].w+tree[tree[root].r].w);
}
int query(int l,int r,int x,int y,int lc,int falc,int k){
	if(l==r) return l;
	int tmp=tree[tree[x].l].w+tree[tree[y].l].w-tree[tree[lc].l].w-tree[tree[falc].l].w;
	int mid=(l+r)>>1;
	if(k<=tmp){
		return query(l,mid,tree[x].l,tree[y].l,tree[lc].l,tree[falc].l,k);
	}
	else{
		return query(mid+1,r,tree[x].r,tree[y].r,tree[lc].r,tree[falc].r,k-tmp);
	}
}
void dfs(int u)
{
	insert(rt[f[u][0]],rt[u],1,n,val[u]);
	for(register int i=head[u];i;i=star[i].nxt){
		int v=star[i].to;
		if(v==f[u][0]) continue;
		dfs(v);
	}
}
int ago[2000010];
signed main()
{
	//freopen("ha.in","r",stdin);
	read(n); read(m);
	inc(i,1,n) read(a[i]),val[i]=a[i];
	inc(i,1,n-1){   
		int u,v;
		read(u); read(v);
		add(u,v);
		add(v,u);
	}		
	sort(a+1,a+1+n); 		
	int lisan=unique(a+1,a+1+n)-a-1;
	inc(i,1,n){
		int tmp=val[i];
		val[i]=lower_bound(a+1,a+1+lisan,val[i])-a;
		ago[val[i]]=tmp;
	}	
	pre(1,0);
	dfs(1);
	int onlineans=0;
	inc(i,1,m){
		int u,v,k;
		read(u);read(v);read(k);
		u^=onlineans;
		int LCA=lca(u,v);
		int last=query(1,n,rt[u],rt[v],rt[LCA],rt[f[LCA][0]],k);
		onlineans=ago[last];
		printf("%d
",onlineans);
	} 
}
原文地址:https://www.cnblogs.com/kamimxr/p/11675572.html