此题我先用的树剖lca然后TLE了,后来改成倍增就过了,为什么呢?是树剖比倍增慢吗?
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define R register
#define int long long
inline int read(){
int a=0,b=1;char c=getchar();
while(!isdigit(c)){if(c=='-')b=-1;c=getchar();}
while(isdigit(c)){a=a*10+c-'0';c=getchar();}
return a*b;
}
const int N=2e5+50,M=4e5+50;
struct node{
int l,r,sum;
}t[6000050];
int n,m,q,a[N],b[N],tot,h[N],ver[M],nx[M],
cnt,d[N],size[N],son[N],top[N],rt[N],f[N][30];//,f[N];
void add(int u,int v){
ver[++tot]=v;nx[tot]=h[u];
h[u]=tot;
}
void build(int &p,int l,int r){
p=++cnt;
if(l==r)return;
int mid=(l+r)>>1;
build(t[p].l,l,mid);build(t[p].r,mid+1,r);
}
void change(int &p,int pre,int l,int r,int k,int z){
p=++cnt;
t[p]=t[pre];t[p].sum+=z;
if(l==r)return;
int mid=(l+r)>>1;
if(k<=mid)change(t[p].l,t[pre].l,l,mid,k,z);
else change(t[p].r,t[pre].r,mid+1,r,k,z);
}
int query(int u,int v,int fa,int faa,int l,int r,int k){
if(l==r)return l;
int sum=t[t[u].l].sum+t[t[v].l].sum-t[t[fa].l].sum-t[t[faa].l].sum;
int mid=(l+r)>>1;
if(k<=sum)return query(t[u].l,t[v].l,t[fa].l,t[faa].l,l,mid,k);
else return query(t[u].r,t[v].r,t[fa].r,t[faa].r,mid+1,r,k-sum);
}
//void dfs1(int x,int fa,int dep){
// f[x]=fa;
// d[x]=dep;
// size[x]=1;
// change(rt[x],rt[fa],1,q,a[x],1);
// int maxson=-1;
// for(R int i=h[x],v;i;i=nx[i]){
// v=ver[i];
// if(v==fa)return;
// dfs1(v,x,dep+1);
// size[x]+=size[v];
// if(size[v]>maxson)maxson=size[v],son[x]=v;
// }
//}
//void dfs2(int x,int topp){
// top[x]=topp;
// if(!son[x])return;
// dfs2(son[x],topp);
// for(R int i=h[x],v;i;i=nx[i]){
// v=ver[i];
// if(v==f[x]||v==son[x])continue;
// dfs2(v,v);
// }
//}
//int lca(int x,int y){
// while(top[x]!=top[y]){
// if(d[top[x]]<d[top[y]])swap(x,y);
// x=f[top[x]];
// }
// return d[x]<d[y]?x:y;
//}
queue<int>qq;
void bfs(){
d[1]=1;qq.push(1);
while(qq.size()){
int x=qq.front();qq.pop();
change(rt[x],rt[f[x][0]],1,q,a[x],1);
for(int i=h[x];i;i=nx[i]){
int v=ver[i];
if(d[v])continue;
d[v]=d[x]+1;
qq.push(v);
f[v][0]=x;
for(int j=1;j<=19;j++){
f[v][j]=f[f[v][j-1]][j-1];
}
}
}
}
int lca(int u,int v){
if(d[u]>d[v])swap(u,v);
for(int i=19;i>=0;i--)
if(d[u]<=d[f[v][i]])v=f[v][i];
if(u==v)return u;
for(int i=19;i>=0;i--)
if(f[u][i]!=f[v][i])u=f[u][i],v=f[v][i];
return f[u][0];
}
signed main(){
n=read();m=read();
for(R int i=1;i<=n;i++){
a[i]=b[i]=read();
}
sort(b+1,b+n+1);
q=unique(b+1,b+n+1)-b-1;
for(R int i=1;i<=n;i++){
a[i]=lower_bound(b+1,b+q+1,a[i])-b;
}
build(rt[0],1,q);
for(R int i=1,u,v;i<n;i++){
u=read();v=read();
add(u,v);add(v,u);
}
// dfs1(1,0,1);dfs2(1,1);
bfs();
for(R int i=1,u,v,k,lca_uv;i<=m;i++){
u=read();v=read();k=read();
lca_uv=lca(u,v);
printf("%lld\n",b[query(rt[u],rt[v],rt[lca_uv],rt[f[lca_uv][0]],1,q,k)]);
}
return 0;
}