看到树上第k大 首先想想普通的前缀和怎么做 假如我要静态的求链(u,v)的和 那么我们就从树根一直搜下来 维护一个前缀和,答案就是
现在再来看主席树的方法就一目了然啦 对于每一个结点 在父节点的基础上建树 然后询问的时候
观察 和k 的大小关系即可
#include<bits/stdc++.h>
#define I inline void
#define R register int
using namespace std;
const int N = 1e5+100;
int n,m;
int sum[N*40],lc[N*40],rc[N*40],rt[N],tot;
int fa[N][30],lg[N],dep[N];
int cur,h[N],nex[N<<1],to[N<<1];
int has[N],val[N],cnt;
inline int in(){
int w=0,x=0;char c=0;
while(c>'9'||c<'0') w|=c=='-',c=getchar();
while(c<='9'&&c>='0') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return w?-x:x;
}
inline int gethas(int x){
return lower_bound(has+1,has+1+cnt,x)-has;
}
I add_edge(R x,R y){
to[++cur]=y;nex[cur]=h[x];h[x]=cur;
}
inline int lca(R x,R y){
if(dep[x]<dep[y]) swap(x,y);
while(dep[x]>dep[y]) x=fa[x][lg[dep[x]-dep[y]]-1];
if(x==y) return x;
for(int i = lg[dep[x]-1]; i >= 0; i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
void update(int &rt,R las,R l,R r,R pos){
rt=++tot;
sum[rt]=sum[las]+1;lc[rt]=lc[las];rc[rt]=rc[las];
if(l==r) return;
int mid = l+r>>1;
if(pos<=mid) update(lc[rt],lc[las],l,mid,pos);
else update(rc[rt],rc[las],mid+1,r,pos);
}
int query(R u,R v,R lca,R flc,R l,R r,R k){
if(l==r) return l;
R g = sum[lc[u]]+sum[lc[v]]-sum[lc[lca]]-sum[lc[flc]];
R mid = l+r>>1;
if(k<=g) return query(lc[u],lc[v],lc[lca],lc[flc],l,mid,k);
else return query(rc[u],rc[v],rc[lca],rc[flc],mid+1,r,k-g);
}
void dfs(int u,int fath){
fa[u][0]=fath,dep[u]=dep[fath]+1;
for(int i = 1; i <= lg[dep[u]]; i++)
fa[u][i]=fa[fa[u][i-1]][i-1];
update(rt[u],rt[fath],1,cnt,gethas(val[u]));
for(int i = h[u]; i; i = nex[i]){
int v = to[i];
if(v==fath) continue;
dfs(v,u);
}
}
int main(){
n=in(),m=in();
for(R i = 1; i < N; i++) lg[i]=lg[i-1]+(1<<lg[i-1]==i);
for(R i = 1; i <= n; i++)
val[i]=in(),has[i]=val[i];
sort(has+1,has+1+n);
cnt=unique(has+1,has+1+n)-has;
for(R i = 1; i <= n-1; i++){
R u,v;
u=in(),v=in();
add_edge(u,v);add_edge(v,u);
}
dfs(1,0);
int last=0;
//printf("tot=%d cur=%d cnt=%d\n",tot,cur,cnt);
for(R i = 1; i <= m; i++){
R u,v,k;
u=in(),v=in(),k=in();
u^=last;
int lcauv=lca(u,v);
//printf("u=%d v=%d lcauv=%d\n",u,v,lcauv);
last=has[query(rt[u],rt[v],rt[lcauv],rt[fa[lcauv][0]],1,cnt,k)];
printf("%d\n",last);
}
return 0;
}