• <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)  編輯 收藏 引用 所屬分類: 線段樹

            狠狠久久综合伊人不卡| 精品久久久久久久久午夜福利| 国产精品美女久久久久网| 久久亚洲欧美国产精品| 久久国产精品成人片免费| 国产成人久久精品一区二区三区| www.久久热.com| 国产精品成人精品久久久| 99久久综合国产精品二区| 欧美粉嫩小泬久久久久久久| 久久99国产精品久久99小说| 人妻无码中文久久久久专区| 好久久免费视频高清| 久久人人爽人爽人人爽av| 狠狠综合久久AV一区二区三区| 久久久久亚洲Av无码专| 国产精品青草久久久久福利99| 久久人人爽人人爽人人爽 | 久久久久一区二区三区| 国产一久久香蕉国产线看观看 | 久久免费视频观看| 久久影院久久香蕉国产线看观看| 麻豆AV一区二区三区久久| 久久久WWW成人免费精品| 久久精品免费一区二区| 国产综合成人久久大片91| 狠狠色丁香久久婷婷综合蜜芽五月| 国产精品对白刺激久久久| 久久久久国产成人精品亚洲午夜| 午夜天堂av天堂久久久| 久久久久久国产精品美女| 国产欧美久久一区二区| 久久久国产精华液| 久久综合九色综合久99| 国产精品内射久久久久欢欢| 激情伊人五月天久久综合| 亚洲精品午夜国产va久久| 精品多毛少妇人妻AV免费久久| 国产亚洲色婷婷久久99精品| 狠狠色婷婷久久一区二区| 久久久午夜精品|