zoukankan      html  css  js  c++  java
  • luogu P1382 楼房

    二次联通门 : luogu P1382 楼房

    /*
        luogu P1382 楼房
    
    
        线段树 + 扫描线 + 离散化 
        正解貌似是堆。。。
        
           MMP。。。二段式线段树各种错误。。。
    
        离散化一下横坐标
        扫描线扫一下就好。。
        
        注意判断一个横坐标上对应两个y值的情况。。。 
    */ 
    #include <algorithm>
    #include <cstdio>
    
    #define Max 1000002
    
    void read (int &now)
    {
        now = 0;
        bool temp = false;
        register char word = getchar ();
        while (word < '0' || word > '9')
        {
            if (word == '-')
                temp = true;
            word = getchar ();
        }
        while (word >= '0' && word <= '9')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
        if (temp)
            now = -now;
    }
    
    inline int min (int _Curs_, int ROcs_)
    {
        return _Curs_ < ROcs_ ? _Curs_ : ROcs_;
    }
    
    inline int max (int _Curs_, int ROcs_)
    {
        return _Curs_ > ROcs_ ? _Curs_ : ROcs_;
    }
    
    struct Segment_Tree_Data
    {
        Segment_Tree_Data *Left, *Right;
        
        int l, r;
        int key;
        int Flandre;
        int Mid;
        
        Segment_Tree_Data ()
        {
            Left = NULL;
            Right = NULL;
            key = 0;
            Flandre = 0;
        }
    };
    
    struct Data_Type
    {
        int l, r;
        int h;
        
        bool operator < (const Data_Type &now) const
        {
            return now.l < l;
        }
    };
    
    struct Point_Data
    {
        int x, y;
    };
    
    Segment_Tree_Data *Root;
    
    class Segment_Tree_Type
    {
        public :
            
            void Build (Segment_Tree_Data *&now, int l, int r)
            {
                now = new Segment_Tree_Data ();
                now->l = l;
                now->r = r;
                if (l == r)
                    return ;
                now->Mid = l + r >> 1;
                
                Build (now->Left, l, now->Mid);
                Build (now->Right, now->Mid + 1, r);
            }
            
            void Change_Section (Segment_Tree_Data *&now, int l, int r, int to)
            {
                if (l <= now->l && r >= now->r)
                {    
                    now->key = max (now->key, to);
                    now->Flandre = max (now->Flandre, to);
                    return ;
                }
                if (now->Flandre)
                {
                    now->Left->key = max (now->Flandre, now->Left->key);
                    now->Right->key = max (now->Flandre, now->Right->key);
                    
                    now->Left->Flandre = max (now->Flandre, now->Left->Flandre);
                    now->Right->Flandre = max (now->Flandre, now->Right->Flandre);
                    
                    now->Flandre = 0;
                }
                if (l <= now->Mid)
                    Change_Section (now->Left, l, min (now->Mid, r), to);
                if (r > now->Mid)
                    Change_Section (now->Right, max (now->Mid + 1, l), r, to);
                now->key = max (now->Left->key, now->Right->key);
            }
            
            int Query (Segment_Tree_Data *&now, int pos)
            {
                if (now->l == now->r)
                    return now->key;
                if (now->Flandre)
                {
                    now->Left->key = max (now->Flandre, now->Left->key);
                    now->Right->key = max (now->Flandre, now->Right->key);
                    
                    now->Left->Flandre = max (now->Flandre, now->Left->Flandre);
                    now->Right->Flandre = max (now->Flandre, now->Right->Flandre);
                    
                    now->Flandre = 0;
                }
                now->key = max (now->Left->key, now->Right->key);
                if (pos <= now->Mid)
                    return Query (now->Left, pos);
                else
                    return Query (now->Right, pos);
            }
    };
    
    Segment_Tree_Type Tree;
    
    
    Data_Type data[Max];
    
    int Answer;
    int rank[Max << 2];
    int N;
    int Size, Count;
    
    Point_Data point[Max];
    
    int main (int argc, char *argv[])
    {
        read (N);
        for (int i = 1; i <= N; i++)
        {
            read (data[i].h);
            read (data[i].l);
            read (data[i].r);
            rank[++Size] = data[i].l;
            rank[++Size] = data[i].r;
        }
        std :: sort (rank + 1, rank + 1 + Size);
        Size = std :: unique (rank + 1, rank + 1 + Size) - rank - 1;
        Root = NULL;
        Tree.Build (Root, 1, Size); 
        for (int i = 1; i <= N; i++)
        {
            data[i].l = std :: lower_bound (rank + 1, rank + 1 + Size, data[i].l) - rank;
            data[i].r = std :: lower_bound (rank + 1, rank + 1 + Size, data[i].r) - rank;
            Tree.Change_Section (Root, data[i].l, data[i].r - 1, data[i].h);
        }
        
        for (int i = 1; i <= Size; i++)
        {
            point[i].x = rank[i];
            point[i].y = Tree.Query (Root, i);
            if (point[i].y != point[i - 1].y)
                Answer++; 
        }
        printf ("%d
    ", Answer << 1);
        for (int i = 1; i <= Size; i++)
            if (point[i].y != point[i - 1].y)
            {
                printf ("%d %d
    ", point[i].x, point[i - 1].y);
                printf ("%d %d
    ", point[i].x, point[i].y);
            }
        return 0;
    }    
  • 相关阅读:
    网络对抗技术 20181216 Exp6 MSF基础应用
    实验一-密码引擎-加密API研究
    网络对抗技术 20181216 Exp5 信息搜集与漏洞扫描
    网络对抗技术 20181216 Exp4 恶意代码分析原理与实践说明
    网络对抗技术 20181216 Exp3 免杀原理与实践
    用Visual Studio 2019 创建C#窗体项目
    EL表达式的学习
    session学习
    mysql+javaWeb+jdbc+tomcat开发中的中文乱码处理
    java集合
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/6936365.html
Copyright © 2011-2022 走看看