给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u和v这两个节点间第K小的点权,强制在线。N,M<=100000
边DFS边建出主席树,这样每次建出的树存储的都是该节点到根的 size 前缀和
这样每次在 rt[u]+rt[v]−rt[lca]−rt[fa[lca]] 四棵树上查询即可
/**************************************************************
Problem: 2588
User: bdzxt
Language: C++
Result: Accepted
Time:4844 ms
Memory:47508 kb
****************************************************************/
#include
#define LL long long
#define clr(x,i) memset(x,i,sizeof(x))
using namespace std;
const int N=100005;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct Edge{
int to,nex;
}e[N*2];
struct Node{
int l,r,sz;
}t[N*25];
int n,m,A[N],rk[N],sz,head[N],pa[N],fa[N][19],dep[N],dfn,ecnt;
int rt[N],tot;
inline void addedge(int u,int v)
{
e[++ecnt]=(Edge){v,head[u]};head[u]=ecnt;
e[++ecnt]=(Edge){u,head[v]};head[v]=ecnt;
}
void upd(int l,int r,int &x,int y,int p)
{
x=++tot;t[x]=t[y];t[x].sz++;
if(l==r) return;
int mid=(l+r)>>1;
if(p<=mid)
upd(l,mid,t[x].l,t[y].l,p);
else
upd(mid+1,r,t[x].r,t[y].r,p);
}
int query(int l,int r,int a,int b,int c,int d,int k)
{
if(l==r) return l;
int sum=t[t[a].l].sz+t[t[b].l].sz-t[t[c].l].sz-t[t[d].l].sz,mid=(l+r)>>1;
if(k<=sum)
return query(l,mid,t[a].l,t[b].l,t[c].l,t[d].l,k);
else
return query(mid+1,r,t[a].r,t[b].r,t[c].r,t[d].r,k-sum);
}
void dfs(int u)
{
//tid[u]=++dfn;pos[dfn]=u;
int val=lower_bound(rk+1,rk+sz+1,A[u])-rk;
upd(1,sz,rt[u],rt[pa[u]],val);
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;if(v==pa[u])continue;
pa[v]=u;dep[v]=dep[u]+1;
dfs(v);
}
}
int LCA(int x,int y)
{
if(dep[x]for(int i=18;i>=0;i--)
if(dep[fa[x][i]]>=dep[y])
x=fa[x][i];
if(x==y)return x;
for(int i=18;i>=0;i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++) A[i]=rk[i]=read();
sort(rk+1,rk+n+1);
sz=unique(rk+1,rk+n+1)-rk-1;
for(int i=1;iint u=read(),v=read();addedge(u,v);
}
dep[1]=1;dfs(1);
for(int i=1;i<=n;i++)fa[i][0]=pa[i];
for(int j=1;j<=18;j++)
for(int i=1;i<=n;i++)
fa[i][j]=fa[fa[i][j-1]][j-1];
int lastans=0;
for(int i=1;i<=m;i++)
{
int u=read()^lastans,v=read(),k=read(),lca=LCA(u,v);
lastans=rk[query(1,sz,rt[u],rt[v],rt[lca],rt[pa[lca]],k)];//记得加rt
printf("%d",lastans);
if(i!=m)putchar('\n');
}
return 0;
}