RT,克鲁斯卡尔重构树+树剖+主席树,第一个点过了,其他 MLE 了,感觉已经无法自己继续优化,特来求助谷内大佬。
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<set>
using namespace std;
const int N=1e5+10;
const int M=5e5+10;
int n,m,q,h[N],a[N<<1],fa[N],cnt,to[N<<1][2];
struct edge{
int x,y,w;
}e[M];
bool cmp(edge x,edge y){
return x.w<y.w;
}
int find(int x){
if(fa[x]==x){
return x;
}
return fa[x]=find(fa[x]);
}
void unify(int x,int y){
fa[find(y)]=find(x);
}
int fat[N],siz[N],son[N],top[N],dfo[N],seq[N];
void dfs1(int x,int f){
fat[x]=f,siz[x]=1;
for(int i=0;i<2;i++){
int v=to[x][i];
if(!v){
continue;
}
dfs1(v,x);
siz[x]+=siz[v];
if(siz[v]>siz[son[x]]){
son[x]=v;
}
}
}
void dfs2(int x,int t){
dfo[x]=++cnt,top[x]=t,seq[cnt]=x;
if(son[x]){
dfs2(son[x],t);
}
for(int i=0;i<2;i++){
int v=to[x][i];
if(!v||v==son[x]){
continue;
}
dfs2(v,v);
}
}
int gr(int x,int k){
while(a[fat[top[x]]]<=k&&fat[top[x]]!=0){
x=fat[top[x]];
}
int l=dfo[top[x]],r=dfo[x],res=x;
while(l<=r){
int mid=(l+r)>>1;
if(a[seq[mid]]<=k){
r=mid-1;
res=seq[mid];
}
else{
l=mid+1;
}
}
return res;//返回编号为res的节点
}
int root[N<<1],tot;
vector <int> num;
struct node{
int l,r,cnt;
}tr[N*18];
int get(int x){
return lower_bound(num.begin(),num.end(),x)-num.begin();
}
int build(int l,int r){
int p=++tot;
if(l==r){
return p;
}
int mid=(l+r)>>1;
tr[p].l=build(l,mid);
tr[p].r=build(mid+1,r);
return p;
}
int insert(int p,int l,int r,int x){
int q=++tot;
tr[q]=tr[p];
if(l==r){
tr[q].cnt++;
return q;
}
int mid=(l+r)>>1;
if(x<=mid){
tr[q].l=insert(tr[p].l,l,mid,x);
}
else{
tr[q].r=insert(tr[p].r,mid+1,r,x);
}
tr[q].cnt=tr[tr[q].l].cnt+tr[tr[q].r].cnt;
return q;
}
int query(int q,int p,int l,int r,int k){
if(l==r){
return r;
}
int cnt=tr[tr[q].l].cnt-tr[tr[p].l].cnt;
int mid=(l+r)>>1;
if(k<=cnt){
return query(tr[q].l,tr[p].l,l,mid,k);
}
else{
return query(tr[q].r,tr[p].r,mid+1,r,k-cnt);
}
}
int main(){
scanf("%d%d%d",&n,&m,&q);
cnt=n;
for(int i=1;i<=n;i++){
scanf("%d",&h[i]);
num.push_back(h[i]);
}
sort(num.begin(),num.end());
num.erase(unique(num.begin(),num.end()),num.end());
for(int i=1;i<=n*2;i++){
fa[i]=i,a[i]=0;
}
for(int i=1;i<=m;i++){
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
}
sort(e+1,e+m+1,cmp);
int x,y,z;
for(int i=1;i<=m;i++){
x=find(e[i].x),y=find(e[i].y);
if(x!=y){
++cnt;
unify(cnt,x),unify(cnt,y);
to[cnt][0]=x,to[cnt][1]=y;
a[cnt]=e[i].w;
}
}
cnt=0;
dfs1(2*n-1,0);
dfs2(2*n-1,2*n-1);
tot=0;
root[0]=build(0,num.size()-1);
for(int i=1;i<=cnt;i++){
if(seq[i]<=n){
root[i]=insert(root[i-1],0,num.size()-1,get(h[seq[i]]));
}
else{
root[i]=root[i-1];
}
}
while(q--){
scanf("%d%d%d",&x,&y,&z);
int rt=gr(x,y);
if(tr[root[dfo[rt]+siz[rt]-1]].cnt-tr[root[dfo[rt]-1]].cnt<z){
printf("-1\n");
}
else{
z=tr[root[dfo[rt]+siz[rt]]].cnt-tr[root[dfo[rt]-1]].cnt-z;
printf("%d\n",num[query(root[dfo[rt]+siz[rt]-1],root[dfo[rt]-1],0,num.size()-1,z)]);
}
}
}