Description
在Bytemountains有N座山峰,每座山峰有他的高度h_i。有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。
Input
第一行三个数N,M,Q。
第二行N个数,第i个数为h_i
接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。
接下来Q行,每行三个数v x k,表示一组询问。
Output
对于每组询问,输出一个整数表示答案。
考虑离线,将边和询问按边权排序,从小到大加入边,平衡树启发式合并维护连通块内点权
#include<cstdio> #include<algorithm> #include<cstdlib> const int M=30000000; char buf[M+4],*ptr=buf-1; inline int _int(){ int x=0,c=*++ptr,f=1; while(c>57||c<48){if(c=='-')f=-1;c=*++ptr;} while(c>47&&c<58)x=x*10+c-48,c=*++ptr; return x; } struct edge{ int s,t,l; }e[500010]; bool operator<(const edge&a,const edge&b){ return a.l<b.l; } struct Q{ int w,mx,k,id; }qs[500010]; bool operator<(const Q&a,const Q&b){ return a.mx<b.mx; } const int N=100010; int n,m,q; int h[N],ans[500010]; int ch[N][2],sz[N],col[N],rt[N],rnd[N]; int stk[N],stp; void dfs(int w){ if(!w)return; dfs(ch[w][0]); stk[stp++]=w; dfs(ch[w][1]); } inline void up(int w){ sz[w]=1+sz[ch[w][0]]+sz[ch[w][1]]; } inline void rot(int&w,int d){ int u=ch[w][d]; ch[w][d]=ch[u][d^1]; ch[u][d^1]=w; up(w); up(w=u); } void ins(int&w,int x){ if(!w){ w=x; return; } ++sz[w]; int d=(h[w]<h[x]); ins(ch[w][d],x); if(rnd[ch[w][d]]>rnd[w])rot(w,d); } int kmax(int w,int k){ if(sz[w]<k||k<=0)return -1; --k; while(1){ int s=sz[ch[w][1]]; if(s==k)return h[w]; if(s<k){ k-=s+1; w=ch[w][0]; }else{ w=ch[w][1]; } } } void merge(int x,int y){ x=col[x];y=col[y]; if(x==y)return; if(sz[rt[x]]<sz[rt[y]]){int z=x;x=y;y=z;} stp=0; dfs(rt[y]); for(int i=0;i<stp;i++){ int w=stk[i]; col[w]=x; sz[w]=1; ch[w][0]=ch[w][1]=0; ins(rt[x],w); } } int main(){ fread(buf,1,M,stdin); srand(1844677); n=_int();m=_int();q=_int(); for(int i=1;i<=n;i++){ h[i]=_int(); sz[rt[i]=col[i]=i]=1; rnd[i]=rand(); } for(int i=0;i<m;i++){ e[i].s=_int(); e[i].t=_int(); e[i].l=_int(); } std::sort(e,e+m); e[m].l=2147483647; for(int i=0;i<q;i++){ qs[i].w=_int(); qs[i].mx=_int(); qs[i].k=_int(); qs[i].id=i; } std::sort(qs,qs+q); for(int i=0,p=0;i<q;i++){ int mx=qs[i].mx; while(e[p].l<=mx){ merge(e[p].s,e[p].t); ++p; } ans[qs[i].id]=kmax(rt[col[qs[i].w]],qs[i].k); } for(int i=0;i<q;i++)printf("%d\n",ans[i]); return 0; }