Peaks题解
Peaks题解
这是一道经典的Kruskal重构树的题目,还是得好好写写,
题目中
每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰
中
从点v开始只经过困难值小于等于x的路径
难以实现
所以我们要借助Kruskal重构树的黑科技,
建一颗Kruskal重构树,
如有不会的敬请请看这里
然后每次询问从一个点往上倍增跳,跳到不能跳为止
这个点以下的点就是能通过困难值<=x的边能到达的点,
根据Kruskal重构树的性质,所有原来节点都在叶子节点,每次查询这个点所代表的叶子区间中第k大值
k大值,用主席树维护即可
#include<bits/stdc++.h>
#define lc son[x][0]
#define rc son[x][1]
using namespace std;
const int N=3e5+6,M=27;
int n,m,Q,tot,cnt=0,num=0,head[N<<1],h[N],f[N<<1],rt[N];
int fa[N<<1][22],maxx[N<<1][22],fst[N<<1],lat[N<<1];
int t1,t2,t3,amt=0,siz,a[N],son[N*20][2],sum[N*20];
struct que{int x,y,z;}q[N];
struct edge{int nxt,to;}e[N<<1];
inline void add(int u,int v){e[++cnt].nxt=head[u],e[cnt].to=v,head[u]=cnt;}
inline int read(){
int T=0,F=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
return F*T;
}
bool cmp(que u,que v){return u.z<v.z;}
int getf(int u){return f[u]==u?u:f[u]=getf(f[u]);}
bool merge(int u,int v,int w){
u=getf(u),v=getf(v);
if(u==v) return false;
++tot,f[u]=f[v]=f[tot]=tot,add(tot,u),add(tot,v);
fa[u][0]=fa[v][0]=tot,maxx[u][0]=maxx[v][0]=w;
return true;
}
void build(int l,int r,int &x){
x=++num; int mid=l+r>>1;
if(l==r) return;
build(l,mid,lc),build(mid+1,r,rc);
sum[x]=sum[lc]+sum[rc];
}
void update(int l,int r,int p,int &x,int y){
if(!x) x=++num;
sum[x]=sum[y]+1;
if(l==r) return;
int mid=l+r>>1;
if(p<=mid) rc=son[y][1],update(l,mid,p,lc,son[y][0]);
else lc=son[y][0],update(mid+1,r,p,rc,son[y][1]);
}
int query(int l,int r,int p,int x,int y){
if(l==r) return l;
int mid=l+r>>1,o=-sum[rc]+sum[son[y][1]];
if(p>o) return query(l,mid,p-o,lc,son[y][0]);
else return query(mid+1,r,p,rc,son[y][1]);
}
void dfs(int x){
for(int i=1;i<=20;++i) fa[x][i]=fa[fa[x][i-1]][i-1],maxx[x][i]=max(maxx[x][i-1],maxx[fa[x][i-1]][i-1]);
fst[x]=amt;
if(!head[x]) ++amt,fst[x]=amt,t1=lower_bound(a+1,a+siz+1,h[x])-a,update(1,siz,t1,rt[amt],rt[amt-1]);
for(int i=head[x];i;i=e[i].nxt) dfs(e[i].to);
lat[x]=amt;
}
int main(){
n=read(),m=read(),Q=read(),tot=n;
for(int i=1;i<=n;++i) h[i]=read(),f[i]=i,a[i]=h[i];
for(int i=1;i<=m;++i) q[i].x=read(),q[i].y=read(),q[i].z=read();
sort(q+1,q+m+1,cmp),sort(a+1,a+n+1),siz=unique(a+1,a+n+1)-a-1;
for(int i=1;i<n;++i){
++num;
if(num>m) break;
if(!merge(q[num].x,q[num].y,q[num].z)) --i;
}
num=0,build(1,siz,rt[0]),dfs(tot);
for(int i=1;i<=Q;++i){
t1=read(),t2=read(),t3=read();
for(int j=20;j>=0;--j) if(fa[t1][j]&&t2>=maxx[t1][j]) t1=fa[t1][j];
if(sum[rt[lat[t1]]]-sum[rt[fst[t1]]]<t3) printf("-1\n");
else printf("%d\n",a[query(1,siz,t3,rt[fst[t1]],rt[lat[t1]])]);
}
return 0;
}