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;
}
posted @ 2019-10-18 07:39  lsoi_ljk123  阅读(170)  评论(0编辑  收藏  举报