总共跑了500多ms,领先第二名的左偏树和第三名的线段树合并(我没看错吧)200多ms。
#include<bits/stdc++.h>
using namespace std;
#define re register
const int N=1e5+5;
const int M=5e5+5;
int n,m,k,a[N],f[N],sz[N],ans[M];
vector<int> g[N];
inline int find(int x){
return f[x]==x?x:f[x]=find(f[x]);
}
struct xx{
int u,v,w;
}e[M];
struct xx2{
int u,k,w,id;
}q[M];
bool cmp(xx ax,xx ay){
return ax.w<ay.w;
}
bool cmp2(xx2 ax,xx2 ay){
return ax.w<ay.w;
}
#define gc getchar_unlocked
inline int rd() {
int x = 0; char ch = gc();
while(ch < '0' || ch > '9') ch = gc();
while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = gc();
return x;
}
int main(){
n=rd(),m=rd(),k=rd();
for(re int i=1;i<=n;i++){
a[i]=rd();
f[i]=i,sz[i]=1,g[i].push_back(a[i]);
}
for(re int i=1;i<=m;i++) e[i].u=rd(),e[i].v=rd(),e[i].w=rd();
sort(e+1,e+m+1,cmp);
for(re int i=1;i<=k;i++){
q[i].u=rd(),q[i].w=rd(),q[i].k=rd();
q[i].id=i;
}
sort(q+1,q+k+1,cmp2);
int cnt=1;
for(re int i=1;i<=k;i++){
//printf("111 %d\n",i);
while(q[i].w>=e[cnt].w&&cnt<=m){
//printf("222 %d\n",cnt);
int fx=find(e[cnt].u),fy=find(e[cnt].v);
if(fx==fy){
cnt++;
continue;
}
int sx=sz[fx],sy=sz[fy];
if(sx==0||sy==0){
cnt++;
continue;
}
if(sx>sy) swap(sx,sy),swap(fx,fy);
f[fx]=fy;
sz[fy]+=sz[fx];
if(sx<=sqrt(sy)){
while(sx--){
int now=g[fx].back();
g[fy].insert(lower_bound(g[fy].begin(),g[fy].end(),now),now);
g[fx].pop_back();
}
}else{
while(sx--){
g[fy].push_back(g[fx].back());
g[fx].pop_back();
}
stable_sort(g[fy].begin(),g[fy].end());
}
cnt++;
}
int fx=find(q[i].u);
if(q[i].k>sz[fx]) ans[q[i].id]=-1;
else ans[q[i].id]=g[fx][sz[fx]-q[i].k];
}
for(re int i=1;i<=k;i++) printf("%d\n",ans[i]);
return 0;
}