【bzoj3545】peaks

离线一下,动态开点+线段树合并,然后权值线段树上询问kth即可。

#include<bits/stdc++.h>
const int N=500005;
const int M=100005*32;
using namespace std;
int n,m,q,ans[N],rt[N],a[N],fa[N],cnt=0;
inline int read(){
    int f=1,x=0;char ch;
    do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
    do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
    return f*x;
}
struct Edge{
    int u,v,w;
    bool operator <(const Edge &x)const{return w<x.w;}
    inline void init(){u=read();v=read();w=read();}
}G[N];
struct Query{
    int v,x,k,id;
    inline void init(int i){v=read();x=read();k=read();id=i;}
    bool operator < (const Query &a)const{return x<a.x;}
}Q[N];
inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
struct Segment_Tree{
    int lc[M],rc[M],val[M];
    void ins(int &o,int l,int r,int q){
        if(!o)o=++cnt;val[o]++;
        if(l==r)return;int mid=(l+r)>>1;
        if(q<=mid)ins(lc[o],l,mid,q);
        else ins(rc[o],mid+1,r,q);
    }
    int merge(int x,int y,int l,int r){
        if(!x)return y;if(!y)return x;
        if(l==r){val[x]+=val[y];return x;}
        int mid=(l+r)>>1;
        lc[x]=merge(lc[x],lc[y],l,mid);
        rc[x]=merge(rc[x],rc[y],mid+1,r);
        val[x]=val[lc[x]]+val[rc[x]];
        return x; 
    }
    int kth(int o,int l,int r,int q){
        if(l==r)return l;
        int mid=(l+r)>>1;
        if(val[rc[o]]>=q)return kth(rc[o],mid+1,r,q);
        return kth(lc[o],l,mid,q-val[rc[o]]);
    }
}T;
inline void uni(int u,int v){
    int x=find(u),y=find(v);
    if(x==y)return;
    rt[x]=T.merge(rt[x],rt[y],1,1e9);
    fa[y]=x;
}
int main(){
    n=read();m=read();q=read();
    for(int i=1;i<=n;i++){
        a[i]=read();fa[i]=i;T.ins(rt[i],1,1e9,a[i]);
    }
    for(int i=1;i<=m;i++)G[i].init();
    sort(G+1,G+m+1);
    for(int i=1;i<=q;i++)Q[i].init(i);
    sort(Q+1,Q+q+1);
    for(int i=1,j=1;i<=q;i++){
        while(j<=m&&G[j].w<=Q[i].x)uni(G[j].u,G[j].v),++j;
        int t=rt[find(Q[i].v)];
        ans[Q[i].id]=T.val[t]>=Q[i].k?T.kth(t,1,1e9,Q[i].k):-1;
    }
    for(int i=1;i<=q;i++)printf("%d\n",ans[i]);
}

 

posted @ 2017-07-26 14:04  zcysky  阅读(242)  评论(0编辑  收藏  举报