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

【洛谷P1382】楼房

时间:2017-10-28 23:15:06      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:for   排序   class   space   name   print   矩形   UI   ++   

这个题先离散化,然后强行用线段树统计每个点的高度,就可以了,只需要区间修改和单点查询就好,不过数据范围可能是假的……因为题目100000,然后我按照线段树开了4倍空间,然后re了,直到开了8倍……

#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
int m;
struct es
{
    int h,x,y;
}ing[200010];
struct in
{
    int l,r,mx,add;
}ter[800040];
int a[800020],len,tot,a1[1000020],a2[1000020];
inline void build(int l,int r,int w)
{
    ter[w].mx=0,ter[w].l=l,ter[w].r=r,ter[w].add=0;
    if(l==r)
        return;
    int mid=l+r>>1;
    build(l,mid,w<<1),build(mid+1,r,w<<1|1); 
}
inline void d(int w)
{
    if(!ter[w].add)
        return;
    ter[w<<1].mx=max(ter[w<<1].mx,ter[w].add);
    ter[w<<1|1].mx=max(ter[w<<1|1].mx,ter[w].add);
    ter[w<<1].add=max(ter[w].add,ter[w<<1].add);
    ter[w<<1|1].add=max(ter[w].add,ter[w<<1|1].add);
    ter[w].add=0;
}
inline void u(int w)
{ 
    ter[w].mx=max(ter[w<<1].mx,ter[w<<1|1].mx);
}
void cha(int l,int r,int x,int w)//区间修改赋值 
{
    if(ter[w].l==l&&ter[w].r==r)
    {
        ter[w].mx=max(ter[w].mx,x),ter[w].add=max(ter[w].add,x);return;
    }
    d(w);
    int mid=ter[w].l+ter[w].r>>1;
    if(r<=mid)
        cha(l,r,x,w<<1);
    else if(l>mid)
        cha(l,r,x,w<<1|1);
    else
        cha(l,mid,x,w<<1),cha(mid+1,r,x,w<<1|1);
    u(w);
}
inline int ask(int l,int w)//单点查询 
{
    if(l==ter[w].l&&l==ter[w].r)
        return ter[w].mx;
    d(w);
    int re=0,mid=ter[w].l+ter[w].r>>1;
    if(l<=mid)
        re=ask(l,w<<1);
    else
        re=ask(l,w<<1|1);
    u(w);
    return re;
}
int main()
{
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&ing[i].h,&ing[i].x,&ing[i].y),a[i*2-1]=ing[i].x,a[i*2]=ing[i].y;
    sort(a+1,a+1+m*2);//排序,之后离散化 
    int len=unique(a+1,a+1+m*2)-a-1;
    build(1,len,1);
    for(int i=1;i<=m;i++)
    {
        int x=lower_bound(a+1,a+1+len,ing[i].x)-a;
        int y=lower_bound(a+1,a+1+len,ing[i].y)-a;
        cha(x,y-1,ing[i].h,1);//因为处理的是区间,有i个点就有i-1个区间 
    }//因为对答案有影响的只有矩形的两端,所以统计答案的时候只关心她们就好 
    for(int i=1;i<=len;i++)
    {
        a1[i]=a[i],a2[i]=ask(i,1);//询问高度 
        if(a2[i]!=a2[i-1])
            tot++;
    }
    printf("%d\n",tot*2);
    for(int i=1;i<=len;i++)
        if(a2[i]!=a2[i-1])//如果高度产生落差,说明这是答案的之一 
        {
            printf("%d %d\n",a1[i],a2[i-1]);
            printf("%d %d\n",a1[i],a2[i]); 
        }
} 

 

【洛谷P1382】楼房

标签:for   排序   class   space   name   print   矩形   UI   ++   

原文地址:http://www.cnblogs.com/Loi-dfkdsmbd/p/7748377.html

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