luoguP1382楼房

Posted yjkhhh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luoguP1382楼房相关的知识,希望对你有一定的参考价值。

题目描述

离散化,线段树维护区间修改,发现询问都是单点的(max),不妨把标记留在点上,不用下传,查询时取个(max)就可以了

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#define lc (p<<1)
#define rc (p<<1|1)
using namespace std;

const int MAXN=400010;
const int MAXM=1600010;

inline int read(){
    int x=0,f=1; char c=getchar();
    while(c<'0'){ if(c=='-') f=-1; c=getchar(); }
    while(c>='0') x=x*10+c-'0',c=getchar();
    return x*f;
}

int n,x[MAXN],cnt,num;

struct Data{
    int l,r,h;
} a[MAXN];

map<int,int> Map;

int tree[MAXM],rev[MAXN];

inline void update(int L,int R,int h,int p=1,int l=1,int r=num){
    if(L<=l&&r<=R){
        tree[p]=max(tree[p],h);
        return;
    }
    int mid=(l+r)>>1;
    if(L<=mid) update(L,R,h,lc,l,mid);
    if(R>mid) update(L,R,h,rc,mid+1,r);
}

inline int query(int x,int p=1,int l=1,int r=num){
    if(l==r) return tree[p];
    int mid=(l+r)>>1,ans=tree[p];
    if(x<=mid) ans=max(ans,query(x,lc,l,mid));
    else ans=max(ans,query(x,rc,mid+1,r));
    return ans;
}

inline bool cmp(Data x,Data y){
    if(x.l!=y.l)
        return x.l<y.l;
    return x.r<y.r;
}

int ansx[MAXN],ansy[MAXN],ansnum;

int main(){
    n=read();
    for(int i=1;i<=n;++i)
        a[i].h=read(),a[i].l=read(),a[i].r=read(),--a[i].r;
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;++i){
        x[++cnt]=a[i].l;
        x[++cnt]=a[i].l+1;
        x[++cnt]=a[i].r;
        x[++cnt]=a[i].r+1;
    }
    x[0]=x[1]-1;
    sort(x+1,x+1+cnt);
    for(int i=1;i<=cnt;++i)
        if(x[i]!=x[i-1]) Map[x[i]]=++num,rev[num]=x[i];
    ++num;
    for(int i=1;i<=n;++i)
        update(Map[a[i].l],Map[a[i].r],a[i].h);
    int last=0;
    for(int i=1;i<=num;++i){
        int tmp=query(i);
        if(tmp!=last){
            if(tmp>last){
                ansx[++ansnum]=rev[i],ansy[ansnum]=last;
                ansx[++ansnum]=rev[i],ansy[ansnum]=tmp;
            }
            else{
                ansx[++ansnum]=rev[i-1]+1,ansy[ansnum]=last;
                ansx[++ansnum]=rev[i-1]+1,ansy[ansnum]=tmp;
            }
            last=tmp;
        }
    }
    printf("%d
",ansnum);
    for(int i=1;i<=ansnum;++i)
        printf("%d %d
",ansx[i],ansy[i]);
    return 0;
}

以上是关于luoguP1382楼房的主要内容,如果未能解决你的问题,请参考以下文章

P1382 楼房

luoguP1382楼房

洛谷P1382楼房

楼房 洛谷1382 && codevs2995

楼房(洛谷 1382)

Luogu1382 楼房 (线段树 扫描线)