zoukankan      html  css  js  c++  java
  • AC日记——楼房 codevs 2995

    2995 楼房

     

     时间限制: 1 s
     空间限制: 256000 KB
     题目等级 : 黄金 Gold
     
     
    题目描述 Description

    地平线(x轴)上有n个矩(lou)形(fang),用三个整数h[i],l[i],r[i]来表示第i个矩形:矩形左下角为(l[i],0),右上角为(r[i],h[i])。地平线高度为0。在轮廓线长度最小的前提下,从左到右输出轮廓线。

    输入描述 Input Description

    第一行一个整数n,表示矩形个数

    以下n行,每行3个整数h[i],l[i],r[i]表示第i个矩形。

    输出描述 Output Description

    第一行一个整数m,表示节点个数

    以下m行,每行一个坐标表示轮廓线上的节点。从左到右遍历轮廓线并顺序输出节点。第一个和最后一个节点的y坐标必然为0。

    样例输入 Sample Input

    【样例输入】

    2
    3 0 2
    4 1 3

    【样例输入2】

    5
    3 -3 0
    2 -1 1
    4 2 4
    2 3 7
    3 6 8

    样例输出 Sample Output

    【样例输出】

    6
    0 0
    0 3
    1 3
    1 4
    3 4
    3 0

    【样例输出2】

    14
    -3 0
    -3 3
    0 3
    0 2
    1 2
    1 0
    2 0
    2 4
    4 4
    4 2
    6 2
    6 3
    8 3
    8 0

    数据范围及提示 Data Size & Hint

    对于30%的数据,n<=100

    对于另外30%的数据,n<=100000,1<=h[i],l[i],r[i]<=1000

    对于100%的数据,1<=n<=100000,1<=h[i]<=10^9,-10^9<=l[i]<r[i]<=10^9

     
    思路:
      离散化+线段树
      有的神犇说扫描线+堆更快,但是我不会。。
      写了一个晚上
      难在离散化和把线段放置
      线段放置要考虑蛮多的情况
      比如
      恰好公用一个端点,可是不重叠
      完全重叠
      等等等等
      离散化,用map记录下来,然后用迭代器全部存起来(stl大法好)
      然后,用离散化好的点的两点之间的间隙建立线段树
      然后把线段排序,从小到大
      然后愉快的裸flag线段树
      然后,像建树一样,一次优化<nlogn的check
      如果前面的间隙的dis不等于现在的间隙的dis就输出
      轻松ac(不知道wa了多少次re多少次)
     
     
    来,上代码:
    #include <map>
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    struct node {
        long long int l,r,dis;
    };
    struct node edge[100001];
    
    inline void read_int(long long int &now_);
    
    class T_tree {
        public:
            int l,r,mid;
            long long int dis,flag;
            
            void mid_()
            {
                mid=(l+r)>>1;
            }
            
            void flag_()
            {
                flag=0;
            }
            
            void dis_()
            {
                dis=0;
            }
    };
    class T_tree tree[100001*4*2];
    
    long long int n,if_Z,num=0,before=0,before_=0;
    long long int point[100001*2],ans=0,ans_now[100001*4],ans_dis[100001*4];
    
    char Cget;
    
    bool if_fi=true;
    
    map<long long int,long long int>if_;
    
    inline void read_int(long long int &now_)
    {
        now_=0,if_Z=1,Cget=getchar();
        while(Cget<'0'||Cget>'9')
        {
            if(Cget=='-') if_Z=-1;
            Cget=getchar();
        }
        while(Cget<='9'&&Cget>='0')
        {
            now_=now_*10+Cget-'0';
            Cget=getchar();
        }
        now_*=if_Z;
    }
    
    inline bool cmp(struct node some1,struct node some2)
    {
        return some1.dis<some2.dis;
    }
    
    void tree_build(int now,int l,int r)
    {
        tree[now].l=l,tree[now].r=r;
        if(l==r)
        {
            tree[now].dis_();
            return ;
        }
        tree[now].mid_();
        tree_build(now<<1,l,tree[now].mid);
        tree_build(now<<1|1,tree[now].mid+1,r);
    }
    
    inline void tree_down(int now)
    {
        if(tree[now].l==tree[now].r) return ;
        tree[now<<1].dis=tree[now].flag;
        tree[now<<1].flag=tree[now].flag;
        tree[now<<1|1].dis=tree[now].flag;
        tree[now<<1|1].flag=tree[now].flag;
        tree[now].flag_();
    }
    
    void tree_change(int now,int l,int r,long long int dis)
    {
        if(tree[now].l==l&&tree[now].r==r)
        {
            tree[now].dis=dis;
            tree[now].flag=dis;
            tree_down(now);
            return ;
        }
        if(tree[now].flag) tree_down(now);
        if(l>tree[now].mid) tree_change(now<<1|1,l,r,dis);
        else if(r<=tree[now].mid) tree_change(now<<1,l,r,dis);
        else
        {
            tree_change(now<<1,l,tree[now].mid,dis);
            tree_change(now<<1|1,tree[now].mid+1,r,dis);
        }
    }
    
    int times=0;
    
    void tree_check(int now)
    {
        if(tree[now].l==tree[now].r)
        {
            if(tree[now].dis!=before)
            {
                ans_now[++ans]=point[tree[now].l];
                ans_dis[ans]=before;
                ans_now[++ans]=point[tree[now].l];
                ans_dis[ans]=tree[now].dis;
                before=tree[now].dis;
            }
            return ;
        }
        if(tree[now].flag) tree_down(now);
        tree_check(now<<1),tree_check(now<<1|1);
    }
    
    int main()
    {
        read_int(n);
        for(int i=1;i<=n;i++)
        {
            read_int(edge[i].dis),read_int(edge[i].l),read_int(edge[i].r);
            if_[edge[i].l]=edge[i].l,if_[edge[i].r]=edge[i].r;
        }
        for(map<long long int,long long int>::iterator it=if_.begin();it!=if_.end();it++)
        {
            point[++num]=it->first;
            it->second=num;
        }
        tree_build(1,1,num+1);
        sort(edge+1,edge+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            tree_change(1,if_[edge[i].l],if_[edge[i].r]-1,edge[i].dis);
        }
        tree_check(1);
        printf("%lld
    ",ans);
        for(int i=1;i<=ans;i++) printf("%lld %lld
    ",ans_now[i],ans_dis[i]);
        return 0;
    }

    附失败代码(>.<):

    #include <map>
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    struct node {
        int l,r,dis;
    };
    struct node edge[100001];
    
    inline void read_int(int &now_);
    
    class T_tree {
        public:
            int l,r,mid,dis,flag;
            
            void mid_()
            {
                mid=(l+r)>>1;
            }
            
            void flag_()
            {
                flag=0;
            }
            
            void dis_()
            {
                //read_int(dis);
                dis=0;
            }
    };
    class T_tree tree[100001*4*2];
    class T_tree ok[100001*4*2];
    
    int n,if_Z,num=0,before=0,before_=0;
    int point[100001*2],ans=0,ans_now[100001*2+1000],ans_dis[100001*2+1000];
    
    char Cget;
    
    bool if_fi=true;
    
    map<int,int>if_;
    
    inline void read_int(int &now_)
    {
        now_=0,if_Z=1,Cget=getchar();
        while(Cget<'0'||Cget>'9')
        {
            if(Cget=='-') if_Z=-1;
            Cget=getchar();
        }
        while(Cget<='9'&&Cget>='0')
        {
            now_=now_*10+Cget-'0';
            Cget=getchar();
        }
        now_*=if_Z;
    }
    
    inline bool cmp(struct node some1,struct node some2)
    {
        return some1.dis<some2.dis;
    }
    
    void ok_build(int now,int l,int r)
    {
        ok[now].l=l,ok[now].r=r;
        if(l==r) return ;
        ok[now].mid_();
        ok_build(now<<1,l,ok[now].mid);
        ok_build(now<<1|1,ok[now].mid+1,r);
    }
    
    void ok_down(int now)
    {
        if(ok[now].l==ok[now].r) return ;
        ok[now<<1].dis=ok[now].flag;
        ok[now<<1].flag=ok[now].flag;
        ok[now<<1|1].dis=ok[now].flag;
        ok[now<<1|1].flag=ok[now].flag;
        ok[now].flag=0;
    }
    
    void ok_change(int now,int l,int r)
    {
        if(ok[now].dis) return ;
        if(ok[now].l==ok[now].r)
        {
            ok[now].dis=1;
            ok[now].flag=1;
            ok_down(now);
            return ;
        }
        if(ok[now].flag) ok_down(now);
        if(l>ok[now].mid) ok_change(now<<1|1,l,r);
        else if(r<=ok[now].mid) ok_change(now<<1,l,r);
        else
        {
            ok_change(now<<1,l,ok[now].mid);
            ok_change(now<<1|1,ok[now].mid+1,r);
        }
    }
    
    bool ok_ko(int now,int to)
    {
        if(ok[now].dis) return true;
        if(ok[now].l==ok[now].r&&ok[now].l==to)
        {
            return false;
        }
        if(ok[now].flag) ok_down(now);
        if(ok[now].l>to) return ok_ko(now<<1|1,to);
        else return ok_ko(now<<1,to);
    }
    
    void tree_build(int now,int l,int r)
    {
        tree[now].l=l,tree[now].r=r;
        if(l==r)
        {
            tree[now].dis_();
            return ;
        }
        tree[now].mid_();
        tree_build(now<<1,l,tree[now].mid);
        tree_build(now<<1|1,tree[now].mid+1,r);
    }
    
    inline void tree_down(int now)
    {
        if(tree[now].l==tree[now].r) return ;
        tree[now<<1].dis=tree[now].flag;
        tree[now<<1].flag=tree[now].flag;
        tree[now<<1|1].dis=tree[now].flag;
        tree[now<<1|1].flag=tree[now].flag;
        tree[now].flag_();
    }
    
    void tree_change(int now,int l,int r,int dis)
    {
        if(tree[now].l==l&&tree[now].r==r)
        {
            tree[now].dis=dis;
            tree[now].flag=dis;
            tree_down(now);
            return ;
        }
        if(tree[now].flag) tree_down(now);
        if(l>tree[now].mid) tree_change(now<<1|1,l,r,dis);
        else if(r<=tree[now].mid) tree_change(now<<1,l,r,dis);
        else
        {
            tree_change(now<<1,l,tree[now].mid,dis);
            tree_change(now<<1|1,tree[now].mid+1,r,dis);
        }
    }
    
    int times=0;
    
    void tree_check(int now)
    {
        if(tree[now].l==tree[now].r)
        {
            /*if(tree[now].dis!=before_)
            {
                times++;
                if(times==1)
                {
                    printf("%d %d
    ",point[tree[now].l],before);
                    printf("%d %d
    ",point[tree[now].l],tree[now].dis);
                }
                else
                {
                    printf("%d %d
    ",point[tree[now].l],tree[now].dis);
                }
                before_=tree[now].dis;
            }*/
            //printf("(%d,%d)",point[tree[now].l],tree[now].dis);
            if(tree[now].l==num+1)
            {
                if(before!=0)
                {
                    //printf("%d %d
    ",point[num],before);
                    //printf("%d %d
    ",point[num],0);
                    ans_now[++ans]=point[num];
                    ans_dis[ans]=before;
                    ans_now[++ans]=point[num];
                    ans_dis[ans]=0;
                }
            }
            else
            {
                if(ok_ko(1,tree[now].l-1))
                {
                    if(tree[now].dis!=before)
                    {
                        //printf("%d %d
    %d %d
    ",point[tree[now].l],before,point[tree[now].l],tree[now].dis);    
                        ans_now[++ans]=point[tree[now].l];
                        ans_dis[ans]=before;
                        ans_now[++ans]=point[tree[now].l];
                        ans_dis[ans]=tree[now].dis;
                        before=tree[now].dis;
                    }
                }
                else
                {
                    if(before!=0)
                    {
                        //printf("%d %d
    ",point[tree[now].l-1],point[tree[now].l]);
                        ans_now[++ans]=point[tree[now].l-1];
                        ans_dis[ans]=before;
                        ans_now[++ans]=point[tree[now].l-1];
                        ans_dis[ans]=0;
                        ans_now[++ans]=point[tree[now].l];
                        ans_dis[ans]=0;
                        ans_now[++ans]=point[tree[now].l];
                        ans_dis[ans]=tree[now].dis;
                        before=tree[now].dis;
                    }
                }
            }
            //printf("(%d %d)
    ",point[tree[now].l],tree[now].dis);
            return ;
        }
        if(tree[now].flag) tree_down(now);
        tree_check(now<<1),tree_check(now<<1|1);
    }
    
    int main()
    {
        read_int(n);
        for(int i=1;i<=n;i++)
        {
            read_int(edge[i].dis),read_int(edge[i].l),read_int(edge[i].r);
            if_[edge[i].l]=edge[i].l,if_[edge[i].r]=edge[i].r;
        }
      //  printf("
    
    ");
        for(map<int,int>::iterator it=if_.begin();it!=if_.end();it++)
        {
            point[++num]=it->first;
            it->second=num;
        //    printf("%d %d
    ",num,point[num]);
        }
        tree_build(1,1,num+1);
        ok_build(1,0,num-1);
        ok_change(1,0,0);
        sort(edge+1,edge+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            printf("%d %d
    ",if_[edge[i].l],if_[edge[i].r]);
        }
        printf("
    
    ");
        for(int i=1;i<=n;i++)
        {
            //printf("%d %d %d
    
    ",if_[edge[i].l],if_[edge[i].r],edge[i].dis);
            tree_change(1,if_[edge[i].l],if_[edge[i].r],edge[i].dis);
               ok_change(1,if_[edge[i].l],if_[edge[i].r]-1);
               printf("%d %d
    ",if_[edge[i].l],if_[edge[i].r]-1);
            //ans=0;
            //before=0;
            //tree_check(1);
            //printf("
    ");
            //printf("%d %d %d
    ",if_[edge[i].l],if_[edge[i].r],edge[i].dis);
        }
        printf("
    
    ");
        //ans=0;
        //before=0;
        tree_check(1);
        //printf("
    
    ");
        printf("%d
    ",ans);
        for(int i=1;i<=ans;i++) printf("%d %d
    ",ans_now[i],ans_dis[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    LOJ#3212. 「CSP-S 2019」划分
    矩阵乘法
    SSF信息社团4月训练题目整理
    AtCoder Regular Contest 116
    SSF信息社团3月训练题目整理
    Codeforces Round #704 (Div. 2)
    SSF信息社团寒假训练题目整理(三)
    关于 zzt 得 0.8 分这件事
    Luogu P7244 章节划分
    SSF信息社团寒假训练题目整理(二)
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6254196.html
Copyright © 2011-2022 走看看