zoukankan      html  css  js  c++  java
  • bzoj3545: [ONTAK2010]Peaks

    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
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    学习方法
    编译原理词法分析程序
    06_05_词法分析
    顺序队列的基本操作
    使用默认参数的构造函数
    基于顺序栈的进制转换
    C语言之大数相加
    输入一个年输出其天干地支纪年法的表达式
    队列的链式存储及其基本运算
    队列的顺序存储及其基本操作
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5622258.html
Copyright © 2011-2022 走看看