• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 97, 文章 - 22, 評論 - 81, 引用 - 0
            數據加載中……

            PKU 3277 City Horizon

            題目鏈接:http://poj.org/problem?id=3277
            /*
            題意:
                給定N(N <= 40000)個矩形,求它們的面積并。

            解法:
            離散化+線段樹

            思路:
                矩形面積并的nlog(n)經典算法。首先我們將每個矩形的縱向邊投
            影到Y軸上,這樣就可以把矩形的縱向邊看成一個閉區間,用線段樹來
            維護這些矩形邊的并。現在求的是矩形的面積并,于是可以枚舉矩形的
            x坐標,然后檢測當前相鄰x坐標上y方向的合法長度,兩者相乘就是其中
            一塊面積,枚舉完畢后就求得了所有矩形的面積并。
                我的線段樹結點描述保存了以下信息:區間的左右端點、結點所在
            數組編號(因為采用靜態結點可以大大節省申請空間的時間)、該結點
            被豎直線段完全覆蓋的次數Cover和當前結點的測度。測度是指相鄰x坐
            標之間有效的y方向的長度的和(要求在該區間內)。于是重點就在于
            如何維護測度,我們將一個矩形分成兩條豎直線段來存儲,左邊的邊稱
            為入邊,右邊的邊則為出邊,然后把所有這些豎直線段按照x坐標遞增排
            序,每次進行插入操作,因為坐標有可能不是整數,所以必須在做這些
            之前將y方向的坐標離散化到數組中,每次插入時如果當前區間被完全覆
            蓋,那么就要對Cover域進行更新,入邊+1,出邊-1。更新完畢后判斷當
            前結點的Cover域是否大于零,如果大于零那么當前節點的測度就是結點
            管理區間在y軸上的實際長度,否則,如果是葉子節點,那么測度為0,
            如果是內部結點,那么測度的值是左右兒子測度的和。這個更新是log(n)
            的,所以,總的復雜度就是nlog(n)。
            */


            #include 
            <iostream>
            #include 
            <vector>
            #include 
            <algorithm>
             
            using namespace std;

            #define maxn 100010
            #define ll __int64

            struct VLine {
                
            int x, y0, y1;
                
            int v;
                VLine() 
            {}
                VLine(
            int _x, int _y0, int _y1, int _v) {
                    x 
            = _x;
                    y0 
            = _y0;
                    y1 
            = _y1;
                    v 
            = _v;
                }

            }
            ;

            int cmp(VLine a, VLine b) {
                
            return a.x < b.x;
            }


            vector
            < VLine > Vl;

            int tmp[maxn], size, tot;

            int n;

            int Binary(int val) {
                
            int l = 0;
                
            int r = tot-1;
                
            while(l <= r) {
                    
            int m = (l + r) >> 1;
                    
            if(tmp[m] == val)
                        
            return m;
                    
            if(val > tmp[m]) {
                        l 
            = m + 1;
                    }
            else
                        r 
            = m - 1;
                }

            }


            struct Tree {
                
            int l, r, root;
                
            int nCover;
                
            int ylen;

                
            void Update();
            }
            T[maxn*4];

            void Tree::Update() {
                
            if(nCover) {
                    ylen 
            = tmp[r] - tmp[l];
                }
            else {
                    
            if(l + 1 == r)
                        ylen 
            = 0;
                    
            else
                        ylen 
            = T[root<<1].ylen + T[root<<1|1].ylen;
                }

            }


            void Build(int root, int l, int r) {
                T[root].l 
            = l;
                T[root].r 
            = r;
                T[root].root 
            = root;
                T[root].nCover 
            = T[root].ylen = 0;
                
            if(l + 1 == r)
                    
            return ;
                
            int mid = (l + r) >> 1;
                Build(root
            <<1, l, mid);
                Build(root
            <<1|1, mid, r);
            }


            void Insert(int root, int l, int r, int val) {
                
            if(l >= T[root].r || T[root].l >= r)
                    
            return ;

                
            if(l <= T[root].l && T[root].r <= r) {
                    T[root].nCover 
            += val;
                    T[root].Update();
                    
            return ;
                }

                Insert(root
            <<1, l, r, val);
                Insert(root
            <<1|1, l, r, val);

                T[root].Update();
            }


            int main() {
                
            int i;
                
            while(scanf("%d"&n) != EOF) {
                    Vl.clear();
                    size 
            = tot = 0;
                    tmp[size
            ++= 0;

                    
            for(i = 0; i < n; i++{
                        
            int x0, x1, y;
                        scanf(
            "%d %d %d"&x0, &x1, &y);
                        Vl.push_back(VLine(x0, 
            0, y, 1));
                        Vl.push_back(VLine(x1, 
            0, y, -1));
                        tmp[size
            ++= y;
                    }


                    sort(Vl.begin(), Vl.end(), cmp);
                    sort(tmp, tmp 
            + size);

                    
            for(i = 0; i < size; i++{
                        
            if(!|| tmp[i] != tmp[i-1]) {
                            tmp[tot
            ++= tmp[i];
                        }

                    }


                    ll ans 
            = 0;
                    Build(
            10, tot-1);

                    
            for(i = 0; i < Vl.size(); i++{
                        
            if(i) {
                            ans 
            += (ll)(Vl[i].x - Vl[i-1].x) * T[1].ylen;
                        }

                        Insert(
            1, Binary(Vl[i].y0), Binary(Vl[i].y1), Vl[i].v);
                    }


                    printf(
            "%I64d\n", ans);
                }


                
            return 0;
            }

            posted on 2011-04-03 19:09 英雄哪里出來 閱讀(1193) 評論(0)  編輯 收藏 引用 所屬分類: 線段樹

            久久精品一本到99热免费| 亚洲成av人片不卡无码久久| 久久国产色av免费看| 精品人妻久久久久久888| 国产成人精品久久亚洲| 女同久久| av无码久久久久不卡免费网站| 精品久久一区二区三区| 亚洲精品国产自在久久| 久久精品国产99久久久| 精品久久人人爽天天玩人人妻| 久久久亚洲AV波多野结衣| 国产成人久久精品一区二区三区| 久久不见久久见免费影院www日本| 亚洲美日韩Av中文字幕无码久久久妻妇 | 久久国产精品国语对白| 亚洲AV日韩AV天堂久久| 久久午夜福利电影| 国产成人精品白浆久久69| 亚洲日本久久久午夜精品| 国产精品久久自在自线观看| 狠狠综合久久综合88亚洲| 青青青国产精品国产精品久久久久 | 久久国产精品无码HDAV| 亚洲午夜精品久久久久久app| 久久99国产精品99久久| 久久午夜羞羞影院免费观看| 亚洲国产精品狼友中文久久久| 久久综合狠狠色综合伊人| 久久亚洲中文字幕精品有坂深雪| 久久久久亚洲精品中文字幕| A级毛片无码久久精品免费| 精品综合久久久久久888蜜芽| 亚洲欧洲日产国码无码久久99| 欧美粉嫩小泬久久久久久久| 久久久精品波多野结衣| 国产精品嫩草影院久久| 一本大道加勒比久久综合| 久久精品国产只有精品2020| 国产三级久久久精品麻豆三级| 久久人人爽爽爽人久久久|