bzoj3545 Peaks 线段树合并

Posted ezoihy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

以上是关于bzoj3545 Peaks 线段树合并的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ3545] [ONTAK2010]Peaks(线段树合并 + 离散化)

线段树合并bzoj3545: [ONTAK2010]Peaks

[bzoj2733]永无乡&&[bzoj3545]Peaks

bzoj3545: [ONTAK2010]Peaks 主席树合并

bzoj3545 [ONTAK2010]Peaksbzoj3551 [ONTAK2010]Peaks加强版

bzoj3545 && bzoj3551 Peaks(离线版&&在线版)