• <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 英雄哪里出來 閱讀(1194) 評論(0)  編輯 收藏 引用 所屬分類: 線段樹

            99久久精品免费国产大片| 久久伊人五月天论坛| 亚洲国产精品成人久久| 国产精品99久久久久久宅男小说 | 精品国产99久久久久久麻豆| 伊人久久大香线蕉成人| 色欲久久久天天天综合网精品| 国产精品一久久香蕉国产线看观看| 久久香蕉综合色一综合色88| 久久频这里精品99香蕉久| 色综合久久久久综合体桃花网| 国内精品久久久久久中文字幕| 久久成人国产精品免费软件| 日韩精品久久久久久| 97精品依人久久久大香线蕉97| 91久久福利国产成人精品| 精品久久久久久无码不卡| 婷婷久久综合九色综合98| 97视频久久久| 久久国产精品偷99| 亚洲国产精品久久久久网站| 久久er99热精品一区二区| 狠狠色丁香久久婷婷综合图片 | 亚洲&#228;v永久无码精品天堂久久| 久久亚洲精品无码VA大香大香| 色偷偷888欧美精品久久久| 精品久久久无码人妻中文字幕豆芽| 欧美午夜A∨大片久久| 久久九九免费高清视频| 久久精品国产91久久综合麻豆自制| 亚洲va久久久噜噜噜久久男同| 日韩欧美亚洲综合久久| 欧美久久一级内射wwwwww.| 日批日出水久久亚洲精品tv| 成人精品一区二区久久久| 国产精品久久久久9999| 久久精品这里热有精品| 99热成人精品热久久669| 久久99精品综合国产首页| 天天久久狠狠色综合| 国产成人综合久久久久久|