给一个 N 个点的无向图,每个点有一个高度,每条边有一个困难度。
多次询问求从 Vi 出发,只经过困难度小于等于 Xi 的边所能到达的点中第 K 高的点。
Kruskal 重构树真是个好东西,既好写又好用。
这道题把树建出来后就变成了求某个点的叶子结点中第 K 大的点。
上面说的某个点就是 Vi 在树中向上跳能跳到的点权 <= Xi 的点,
这个东西显然可以用倍增来求。
因为是求第 K 大,所以还要套一个主席树。
1 #include<bits/stdc++.h> 2 #define rep(i,a,b) for(register int i=a;i<=b;++i) 3 #define rpd(i,a,b) for(register int i=a;i>=b;--i) 4 #define rep1(i,x) for(register int i=head[x];i;i=nxt[i]) 5 typedef long long ll; 6 const int N=5e5+5,M=5e5+5; 7 using namespace std; 8 inline int read(){ 9 int x=0,f=1;char ch=getchar(); 10 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 11 while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} 12 return x*f; 13 } 14 struct edge{int x,y,z;}e[M]; 15 bool cmp(edge i,edge j){return i.z<j.z;} 16 int n,m,Q,tot,cnt,sum,rt; 17 int H[N],bing[N<<1],head[N<<1],to[N<<1],nxt[N<<1],w[N<<1],h[N],Ls[N],Rs[N]; 18 void add(int u,int v){nxt[++tot]=head[u];head[u]=tot;to[tot]=v;} 19 int get(int x){return bing[x]==x?x:bing[x]=get(bing[x]);} 20 void buildkt(){ 21 rep(i,1,n<<1)bing[i]=i; 22 sort(e+1,e+m+1,cmp);cnt=n; 23 rep(i,1,m){ 24 int x=get(e[i].x),y=get(e[i].y),z=e[i].z; 25 if(x==y)continue; 26 w[++cnt]=z;add(cnt,x);add(cnt,y); 27 bing[x]=bing[y]=cnt; 28 if(cnt==(n<<1)-1)break; 29 } 30 } 31 int f[N][25],hs[N],id[N]; 32 void dfs(int x,int fa){ 33 f[x][0]=fa;Ls[x]=n+1;Rs[x]=0; 34 if(x<=n){h[++sum]=H[x];Ls[x]=Rs[x]=sum;return;} 35 rep1(i,x){ 36 int p=to[i];dfs(p,x); 37 Ls[x]=min(Ls[x],Ls[p]); 38 Rs[x]=max(Rs[x],Rs[p]); 39 } 40 } 41 void init(){rep(j,1,17)rep(i,1,(n<<1)-1)f[i][j]=f[f[i][j-1]][j-1];} 42 int work(int start,int dis){rpd(i,17,0){int k=f[start][i];if(k==0||w[k]>dis)continue;start=k;}return start;} 43 struct Tree{int x,l,r;}t[N<<5];int ban[N]; 44 void up(int k){t[k].x=t[t[k].l].x+t[t[k].r].x;} 45 void build(int &k,int l,int r){k=++rt;if(l==r)return;int mid=l+r>>1;build(t[k].l,l,mid);build(t[k].r,mid+1,r);} 46 void change(int k,int &k1,int l,int r,int p){ 47 k1=++rt;t[k1]=t[k];if(l==r){t[k1].x+=1;return;} 48 int mid=l+r>>1; 49 if(mid>=p)change(t[k].l,t[k1].l,l,mid,p); 50 else change(t[k].r,t[k1].r,mid+1,r,p); 51 up(k1); 52 } 53 int find(int k,int k1,int l,int r,int p){ 54 if(l==r)return hs[l]; 55 int mid=l+r>>1,opt=t[t[k1].r].x-t[t[k].r].x; 56 if(opt>=p)return find(t[k].r,t[k1].r,mid+1,r,p); 57 return find(t[k].l,t[k1].l,l,mid,p-opt); 58 } 59 int main(){ 60 n=read();m=read();Q=read(); 61 rep(i,1,n)H[i]=read(); 62 rep(i,1,m)e[i].x=read(),e[i].y=read(),e[i].z=read(); 63 buildkt();dfs((n<<1)-1,0);init(); 64 rep(i,1,n)hs[i]=h[i];sort(hs+1,hs+n+1); 65 rep(i,1,n)id[i]=lower_bound(hs+1,hs+n+1,h[i])-hs; 66 build(ban[0],1,n); 67 rep(i,1,n)change(ban[i-1],ban[i],1,n,id[i]); 68 //rep(i,1,n)cout<<i<<' '<<h[i]<<endl; 69 while(Q--){ 70 int v=read(),x=read(),k=read(),root=work(v,x),L=Ls[root],R=Rs[root]; 71 //cout<<L<<' '<<R<<endl; 72 if(k>R-L+1){puts("-1");continue;} 73 printf("%d\n",find(ban[L-1],ban[R],1,n,k)); 74 } 75 //system("pause"); 76 return 0; 77 }