#Kruskal重构树,主席树,倍增#洛谷 4197 Peaks
分析
首先第\(k\)大一般都是主席树
问题是困难值的限制有点束手无措
又是\(\text{Kruskal重构树}\)
将困难值为边权跑最小生成树,重新建树,实际上让困难值跳到尽量大的位置就可以了,那可以倍增实现
然后找到这个点,实际可以按照dfs序代表一个区间,那么可以转换为区间求解
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=100011;
struct Chair{
int w[N<<5],ls[N<<5],rs[N<<5],cnt;
inline void build(int &rt,int l,int r){
w[rt=++cnt]=0; rr int mid=(l+r)>>1;
if (l<r) build(ls[rt],l,mid),build(rs[rt],mid+1,r);
}
inline void update(int &rt,int l,int r,int k){
rr int trt=++cnt,mid=(l+r)>>1;
ls[trt]=ls[rt],rs[trt]=rs[rt],w[trt]=w[rt]+1,rt=trt;
if (l==r) return;
k<=mid?update(ls[trt],l,mid,k):update(rs[trt],mid+1,r,k);
}
inline signed query(int L,int R,int l,int r,int k){
if (l==r) return l;
rr int x=w[rs[R]]-w[rs[L]],mid=(l+r)>>1;
return x<k?query(ls[L],ls[R],l,mid,k-x):query(rs[L],rs[R],mid+1,r,k);
}
}Tre;
struct node{int y,next;}e[N<<1]; struct rec{int x,y,w;}T[N*5];
int d[N<<1],ls[N<<1],fat[N<<1],f[N<<1][18],lfn[N<<1],rfn[N<<1];
int Dfn,n,k=1,m,Q,sn,dep[N<<1],rt[N],h[N],b[N],tot;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
bool cmp(rec x,rec y){return x.w<y.w;}
inline void add(int x,int y){e[++k]=(node){y,ls[x]},ls[x]=k;}
inline signed getf(int u){return fat[u]==u?u:fat[u]=getf(fat[u]);}
inline void Kruskal(){
for (rr int i=1;i<n*2;++i) fat[i]=i;
for (rr int i=1,tOt=0;i<=m;++i){
rr int fa=getf(T[i].x),fb=getf(T[i].y);
if (fa!=fb){
fat[fa]=fat[fb]=++sn,d[sn]=T[i].w;
add(sn,fa),add(sn,fb);
if (++tOt==n-1) return;
}
}
}
inline void dfs(int x,int fa){
f[x][0]=fa,lfn[x]=Dfn,dep[x]=dep[fa]+1;
for (rr int i=1;i<18;++i)
f[x][i]=f[f[x][i-1]][i-1];
if (!ls[x]){
lfn[x]=++Dfn;
Tre.update(rt[Dfn]=rt[Dfn-1],1,tot,h[x]);
}
for (rr int i=ls[x];i;i=e[i].next) dfs(e[i].y,x);
rfn[x]=Dfn;
}
signed main(){
Tre.cnt=0,sn=n=iut(),m=iut(),Q=iut();
for (rr int i=1;i<=n;++i) h[i]=b[i]=iut();
sort(b+1,b+1+n),tot=unique(b+1,b+1+n)-b-1;
for (rr int i=1;i<=n;++i) h[i]=lower_bound(b+1,b+1+tot,h[i])-b;
for (rr int i=1;i<=m;++i) T[i]=(rec){iut(),iut(),iut()};
sort(T+1,T+1+m,cmp),Kruskal(),Tre.build(rt[0],1,tot),dfs(sn,0);
while (Q--){
rr int x=iut(),D=iut(),Kth=iut();
for (rr int i=17;~i;--i) if (f[x][i]&&d[f[x][i]]<=D) x=f[x][i];
if (rfn[x]-lfn[x]<Kth) putchar('-'),putchar(49),putchar(10);
else print(b[Tre.query(rt[lfn[x]],rt[rfn[x]],1,tot,Kth)]),putchar(10);
}
return 0;
}