• BZOJ3545: [ONTAK2010]Peaks


    题解:离线排序处理  并查集维护边 对于不同集合的启发式合并平衡树 查询第K大即可

    /**************************************************************
        Problem: 3545
        User: c20161007
        Language: C++
        Result: Accepted
        Time:9736 ms
        Memory:19868 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    #define ll long long
    const int NM=1e5+10;
    const int nm=5e5+10;
    using namespace std;
    int ch[NM][2],size[NM],key[NM],pre[NM];
    int f[NM];
    struct FastIO
    {
        static const int S=200;
        int wpos;
        char wbuf[S];
        FastIO():wpos(0){}
        inline int xchar()
        {
            static char buf[S];
            static int len=0,pos=0;
            if(pos==len) pos=0,len=fread(buf,1,S,stdin);
            if(pos==len) exit(0);
            return buf[pos++];
        }
        inline int read()
        {
            int s=1,c=xchar(),x=0;
            while(c<=32) c=xchar();
            if(c=='-') s=-1,c=xchar();
            for(;'0'<=c&&c<='9';c=xchar()) x=x*10+c-'0';
            return x*s;
        }
        ~FastIO()
        {
            if(wpos) fwrite(wbuf,1,wpos,stdout),wpos=0;
        }
    }io;
    typedef struct Edge{
        int u,v;int vul;
        friend bool operator<(Edge aa,Edge bb){
        return aa.vul<bb.vul;
        }
    }Edge;
    Edge ed[nm];
    typedef struct node{
        int v,x,k;int id;
        friend bool operator<(node aa,node bb){
        return aa.x<bb.x;
        }
    }node;
    node que[nm];
    void newnode(int x){
        pre[x]=0;ch[x][0]=ch[x][1]=0;size[x]=1;
    }
    int n,m,q;
    int find1(int x){
        if(f[x]==x)return x;
        else return f[x]=find1(f[x]);
    }
    void up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;}
    void rotate(int x,int kind){
        int y=pre[x];
        ch[y][!kind]=ch[x][kind];pre[ch[x][kind]]=y;
        if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;
        pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
        up(y);
    }
    void splay(int x){
        while(pre[x]!=0){
        if(pre[pre[x]]==0)rotate(x,ch[pre[x]][0]==x);
        else{
            int y=pre[x];int kind=ch[pre[y]][0]==y;
            if(ch[y][kind]==x)rotate(x,!kind),rotate(x,kind);
            else rotate(y,kind),rotate(x,kind);
        }
        }
        up(x);
    }
    void insert(int &x,int pos,int fa){
        if(!x){x=pos;pre[pos]=fa;return ;}
        if(key[x]>key[pos])insert(ch[x][1],pos,x);
        else insert(ch[x][0],pos,x);
        up(x);
    }
    int S[NM];
    void dfs(int x){
        if(!x)return ;
        S[++S[0]]=x;
        dfs(ch[x][0]);
        dfs(ch[x][1]);
    }
    void merge(int u,int v){
        splay(u);splay(v);
        if(size[u]>size[v])swap(u,v);
        S[0]=0;dfs(u);int t=v;
        for(int i=1;i<=S[0];i++)newnode(S[i]),insert(t,S[i],0),splay(S[i]),t=S[i];
        //splay(S[S[0]]);
    }
    int find2(int x,int sz){
        if(sz==size[ch[x][0]]+1)return x;
        else if(sz<=size[ch[x][0]])return find2(ch[x][0],sz);
        else return find2(ch[x][1],sz-size[ch[x][0]]-1);
    }
    int querty(int v,int k){
        splay(v);
        if(size[v]<k)return -1;
        return key[find2(v,k)];
    }
    int ans[nm];
    int main(){
        n=io.read();m=io.read();q=io.read();
        for(int i=1;i<=n;i++)key[i]=io.read(),newnode(i),f[i]=i;
        for(int i=1;i<=m;i++)ed[i].u=io.read(),ed[i].v=io.read(),ed[i].vul=io.read();
        for(int i=1;i<=q;i++)que[i].v=io.read(),que[i].x=io.read(),que[i].k=io.read(),que[i].id=i;
        sort(ed+1,ed+m+1);sort(que+1,que+1+q);
        int l=1;
        for(int i=1;i<=q;i++){
        while(l<=m&&que[i].x>=ed[l].vul){
            int t1=find1(ed[l].u);int t2=find1(ed[l].v);
            if(t1!=t2){
            merge(t1,t2);f[t1]=t2;
            }
            l++;
        }
        ans[que[i].id]=querty(que[i].v,que[i].k);
        }
        for(int i=1;i<=q;i++)printf("%d
    ",ans[i]);
        return 0;
    }
    

    3545: [ONTAK2010]Peaks

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 3083  Solved: 837
    [Submit][Status][Discuss]

    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

    对于每组询问,输出一个整数表示答案。

    Sample Input

    10 11 4
    1 2 3 4 5 6 7 8 9 10
    1 4 4
    2 5 3
    9 8 2
    7 8 10
    7 1 4
    6 7 1
    6 4 8
    2 1 5
    10 8 10
    3 4 7
    3 4 6
    1 5 2
    1 5 6
    1 5 8
    8 9 2

    Sample Output

    6
    1
    -1
    8


    HINT

    【数据范围】

    N<=10^5, M,Q<=5*10^5,h_i,c,x<=10^9。

  • 相关阅读:
    JAVA类加载机制
    redis 持久化的两种方式
    java动态代理(JDK和cglib)
    数据库事务的四大特性以及事务的隔离级别
    数据库范式
    Cookie/Session机制详解
    java多线程并发系列之闭锁(Latch)和栅栏(CyclicBarrier)
    BIO与NIO、AIO的区别
    高性能Server---Reactor模型
    Netty---相关
  • 原文地址:https://www.cnblogs.com/wang9897/p/9426065.html
Copyright © 2020-2023  润新知