码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj3545 Peaks 线段树合并

时间:2018-08-15 16:55:34      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:n+1   i++   str   for   merge   ios   scan   就是   cost   

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

#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\n",ans[i]);
    }
    return 0;
}

bzoj3545 Peaks 线段树合并

标签:n+1   i++   str   for   merge   ios   scan   就是   cost   

原文地址:https://www.cnblogs.com/ezoihy/p/9482014.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!