【BZOJ2588】【Spoj10628】—Count on a tree(主席树)

传送门

题意:求树上路径第kk大值


主席树菜题

树上主席树就完了

#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<21|1;
inline char gc(){
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ob==ib)?EOF:*ib++;
}
inline int read(){
	char ch=gc();
	int res=0,f=1;
	while(!isdigit(ch))f^=ch=='-',ch=gc();
	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
	return f?res:-res;
}
const int N=100005;
namespace Ptree{
	#define mid ((l+r)>>1)
	int rt[N],lc[N*22],rc[N*22],sum[N*22],tot;
	void insert(int &u,int r1,int l,int r,int k){
		u=++tot,lc[u]=lc[r1],rc[u]=rc[r1],sum[u]=sum[r1]+1;
		if(l==r)return;
		if(k<=mid)insert(lc[u],lc[r1],l,mid,k);
		else insert(rc[u],rc[r1],mid+1,r,k);
	}
	int query(int r1,int r2,int r3,int r4,int l,int r,int k){
		if(l==r)return l;
		int num=sum[lc[r4]]+sum[lc[r3]]-sum[lc[r1]]-sum[lc[r2]];
		if(k<=num)return query(lc[r1],lc[r2],lc[r3],lc[r4],l,mid,k);
		else return query(rc[r1],rc[r2],rc[r3],rc[r4],mid+1,r,k-num);
	}
}
using namespace Ptree;
int adj[N],nxt[N<<1],to[N<<1],val[N],a[N],cnt,n,m,top[N],dep[N],siz[N],son[N],fa[N],last;
void dfs1(int u){
	siz[u]=1;insert(rt[u],rt[fa[u]],1,cnt,val[u]);
	for(int e=adj[u];e;e=nxt[e]){
		int v=to[e];
		if(v==fa[u])continue;
		fa[v]=u,dep[v]=dep[u]+1;
		dfs1(v),siz[u]+=siz[v];
		if(siz[v]>siz[son[u]])son[u]=v;
	}
}
void dfs2(int u,int tp){
	top[u]=tp;
	if(son[u])dfs2(son[u],tp);
	for(int e=adj[u];e;e=nxt[e]){
		int v=to[e];
		if(v==fa[u]||v==son[u])continue;
		dfs2(v,v);
	}
}
inline int Lca(int u,int v){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]])swap(u,v);
		u=fa[top[u]];
	}
	return dep[u]>dep[v]?v:u;
}
inline void addedge(int u,int v){
	nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v;
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++)val[i]=a[i]=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		addedge(u,v),addedge(v,u);
	}
	cnt=0;
	sort(a+1,a+n+1);
	cnt=unique(a+1,a+n+1)-a-1;
	for(int i=1;i<=n;i++)val[i]=lower_bound(a+1,a+cnt+1,val[i])-a;
	dfs1(1),dfs2(1,1);
	while(m--){
		int u=read()^last,v=read(),k=read();
		int lca=Lca(u,v);
		cout<<(last=a[query(rt[fa[lca]],rt[lca],rt[u],rt[v],1,cnt,k)])<<'\n';
	}
}
posted @ 2019-04-24 17:32  Stargazer_cykoi  阅读(61)  评论(0编辑  收藏  举报