传送门
乍看像是树剖,但是树剖的话就不能用权值线段树,不能权值线段树求区间第k小就只能树套树,诶静态的当然主席树啦!!
树剖也不需要了诶,好像只需要dfs建主席树就好了,这样建出来的主席树(rt[i]),所包含的就是根到(i)节点路径上的点,对于查询((x,y))就可以差分解决了;
也就是查询((root,x)+(root,y)-(root,lca(x,y))-(root,f[lca(x,y)]))
差分部分具体可以看代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
void read(int &x) {
char ch; bool ok;
for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
}
map<int,int>mp;
const int maxn=1e5+1;
int cnt,n,m,lastans,id,rt[maxn],d[maxn],tot,ff[maxn],ls[maxn*20],rs[maxn*20],size[maxn*20],h[maxn],nxt[maxn*2],pre[maxn*2],dep[maxn],f[maxn][20],w[maxn];
#define rg register
void update(int x){size[x]=size[ls[x]]+size[rs[x]];}
void change(int x,int &k,int l,int r,int a)
{
k=++id,ls[k]=ls[x],rs[k]=rs[x],size[k]=size[x];
if(l==r){size[k]++;return ;}
int mid=(l+r)>>1;
if(a<=mid)change(ls[x],ls[k],l,mid,a);
else change(rs[x],rs[k],mid+1,r,a);
update(k);
}
void add(int x,int y)
{
pre[++cnt]=y,nxt[cnt]=h[x],h[x]=cnt;
pre[++cnt]=x,nxt[cnt]=h[y],h[y]=cnt;
}
void dfs(int x,int fa)
{
for(rg int i=1;i<20;i++)
{
if((1<<i)>dep[x])break;
f[x][i]=f[f[x][i-1]][i-1];
}
change(rt[fa],rt[x],1,tot,mp[d[x]]);
for(rg int i=h[x];i;i=nxt[i])if(pre[i]!=fa)f[pre[i]][0]=x,dep[pre[i]]=dep[x]+1,dfs(pre[i],x);
}
int lca(int x,int y)
{
if(dep[x]>dep[y])swap(x,y);
int poor=dep[y]-dep[x];
for(rg int i=19;i>=0;i--)if(poor&(1<<i))y=f[y][i];
for(rg int i=19;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
return x==y?x:f[y][0];
}
int get(int a,int b,int c,int d,int l,int r,int k)
{
if(l==r)return w[l];
int mid=(l+r)>>1,now=size[ls[a]]+size[ls[b]]-size[ls[c]]-size[ls[d]];
if(k<=now)return get(ls[a],ls[b],ls[c],ls[d],l,mid,k);
else return get(rs[a],rs[b],rs[c],rs[d],mid+1,r,k-now);
}
int main()
{
read(n),read(m);
for(rg int i=1;i<=n;i++)read(d[i]),ff[i]=d[i];
sort(ff+1,ff+n+1);
for(rg int i=1;i<=n;i++)if(!mp[ff[i]])mp[ff[i]]=++tot,w[tot]=ff[i];
for(rg int i=1,x,y,z;i<n;i++)read(x),read(y),add(x,y);
dfs(1,0);
for(rg int i=1,x,y,z,fa;i<=m;i++)
{
read(x),read(y),read(z),x^=lastans;fa=lca(x,y);
printf("%d
",lastans=get(rt[x],rt[y],rt[fa],rt[f[fa][0]],1,tot,z));
}
}