zoukankan      html  css  js  c++  java
  • bzoj3545 Peaks 线段树合并

    离线乱搞。。。
    也就是一个线段树合并没什么

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
     
    using namespace std;
     
    int n,m,q,tot,cnt,num,h[100001],a[100001],ans[500001],fa[100001],root[100001];
     
    struct edge{
        int u,v,cost;
        bool operator < (const edge &b) const{
            return cost<b.cost;
        }
    }e[500001];
     
    struct Que{
        int id,v,x,k;
        bool operator < (const Que &b) const{
            return x<b.x;
        }
    }que[500001];
     
    struct node{
        int lch,rch,siz;
    }tree[2000001];
     
    int find(int x){
        if(fa[x]==x)return x;
        return fa[x]=find(fa[x]);
    }
     
    void insert(int o,int l,int r,int x){
        tree[o].siz++;
        if(l==r)return;
        int mid=(l+r)>>1;
        if(x<=mid){
            if(!tree[o].lch)tree[o].lch=++num;
            insert(tree[o].lch,l,mid,x);
        }
        if(x>mid){
            if(!tree[o].rch)tree[o].rch=++num;
            insert(tree[o].rch,mid+1,r,x);
        }
    }
     
    int query(int o,int l,int r,int k){
        if(k<=0 or k>tree[o].siz)return -1;
        if(l==r)return l;
        int mid=(l+r)>>1;
        if(k<=tree[tree[o].lch].siz)return query(tree[o].lch,l,mid,k);
        return query(tree[o].rch,mid+1,r,k-tree[tree[o].lch].siz);
    }
     
    int merge(int x,int y){
        if(!x or !y)return x+y;
        tree[x].siz+=tree[y].siz;
        tree[x].lch=merge(tree[x].lch,tree[y].lch);tree[x].rch=merge(tree[x].rch,tree[y].rch);
        return x;
    }
     
    int main(){
        scanf("%d%d%d",&n,&m,&q);
        for(int i=1;i<=n;i++){
            scanf("%d",&h[i]);
            a[i]=h[i];fa[i]=i;
        }
        sort(a+1,a+n+1); 
        for(int i=1;i<=n;i++)h[i]=lower_bound(a+1,a+n+1,h[i])-a;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].cost);
        }
        sort(e+1,e+m+1);
        for(int i=1;i<=q;i++){
            scanf("%d%d%d",&que[i].v,&que[i].x,&que[i].k);que[i].id=i;
        }
     
        for(int i=1;i<=n;i++){
            fa[i]=i;
            root[i]=++num;
            insert(root[i],1,n,h[i]);
        }
        sort(que+1,que+q+1);
        for(int i=1;i<=q;i++){
            while(cnt<m and e[cnt+1].cost<=que[i].x){
                int fx=find(e[++cnt].u);
                int fy=find(e[cnt].v);
                if(fx==fy)continue;
                fa[fx]=fy;
                root[fy]=merge(root[fx],root[fy]);
            }
            int rot=root[find(que[i].v)],ret=query(rot,1,n,tree[rot].siz-que[i].k+1);
            ans[que[i].id]=~ret?a[ret]:ret;
        }
        for(int i=1;i<=q;i++){
            printf("%d
    ",ans[i]);
        }
        return 0;
    }
    
    
  • 相关阅读:
    【Go语言】I/O专题
    【Go语言】集合与文件操作
    【Go语言】LiteIDE使用的个人使用方法
    【Go语言】错误与异常处理机制
    【Go语言】面向对象扩展——接口
    【Go语言】学习资料
    创建型模式(前引)简单工厂模式Simple Factory
    redis demo
    导出CSV格式
    mongo聚合命令
  • 原文地址:https://www.cnblogs.com/ezoihy/p/9482014.html
Copyright © 2011-2022 走看看