• <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
            數(shù)據(jù)加載中……

            HDU 3458 Rectangles Too!

            題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3458

            /*
            題意:
                給定n(1<= n <= 100000)個矩形,問最長的遞增矩形序列。矩形A和B
            A = ((xA1 , yA1 ), (xA2 ,yA2 )) 和 B = ((xB1 , yB1 ), (xB2 , yB2 )), 
            如果xA2 < xB1 and yA2 < yB1 則 A <= B,問最長L1 <= L2  <= Ln的長度。

            解法:
            二維線段樹

            思路:
                首先將矩形按左下角x坐標(biāo)排序,相同的按y坐標(biāo)排序,接下來就是對于矩形
            A,能否在(xA1 - 1, yA1 - 1)到負(fù)無窮之間找到一個先前矩形序列的最大值,如
            果能就將當(dāng)前矩形接在其后形成新的最大值,這里涉及到了兩個操作,一個是詢問
            ,然后是插入,詢問的是二維區(qū)間的最大值,插入的時候是在二維區(qū)間的點操作,
            所以很容易想到用二維線段樹來維護(hù)每次操作,這題需要注意的是點比較離散,而
            且詢問不是隨意的給出的,而且一開始二維空間是沒有值的,所以不需要預(yù)先建樹
            ,事實證明,預(yù)先建樹會耗費(fèi)很大的時間,完全是不必要的。先來談?wù)劜迦氩僮鳎?br>我們沒有預(yù)先建樹,所以根結(jié)點一開始的下標(biāo)定為-1,這樣在插入的時候如果發(fā)現(xiàn)
            根結(jié)點的下標(biāo)為-1,就生成一個新的結(jié)點(只需要將計數(shù)器賦值給根結(jié)點的編號即
            可),然后將根結(jié)點的四個兒子全部標(biāo)記為-1,表示并沒有創(chuàng)建兒子,遞歸四個兒
            子,做同樣的操作,直到只剩一個點的時候。然后是詢問,詢問時如果詢問區(qū)間和
            訪問到的結(jié)點區(qū)間沒有交集自然是直接返回,還有一個剪枝,就是如果當(dāng)前結(jié)點還
            未生成(標(biāo)記值為-1)說明之前并沒有在以它為根結(jié)點的子樹中插入值,也直接返
            回。最后一種情況是當(dāng)前結(jié)點為根的子樹的最大值已經(jīng)小于等于當(dāng)前的最大值,也
            直接返回即可。
                二維線段樹的思想類似ZJU 2859 Matrix Searching,只不過一個求的是最大值
            ,一個是最小值。
            */


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

            #define maxn 100010*4

            struct Tree {
                
            int Max;
                
            int son[4];
                
            void clear() {
                    
            int i;
                    
            for(i = 0; i < 4; i++)
                        son[i] 
            = -1;
                    Max 
            = 0;
                }

            }
            T[4*maxn];
            int Tree_Id;

            struct Rectangle {
                
            int x0, x1, y0, y1;
                Rectangle()
            {}
                Rectangle(
            int _x0, int _x1, int _y0, int _y1) {
                    x0 
            = _x0; x1 = _x1;
                    y0 
            = _y0; y1 = _y1;
                }

            }
            ;
            vector 
            < Rectangle > Rec;

            bool cmp(Rectangle a, Rectangle b) {
                
            return a.x0 < b.x0 || (a.x0 == b.x0 && a.y0 < b.y0);
            }


            int Max(int a, int b) {
                
            return a > b ? a : b;
            }

            int Min(int a, int b) {
                
            return a < b ? a : b;
            }


            void Query(int root, int sx, int ex, int sy, int ey, int x0, int x1, int y0, int y1, int& Max) {
                
            if(sx > x1 || ex < x0 || sy > y1 || ey < y0 || root == -1 || T[root].Max <= Max)
                    
            return ;

                
            if(sx <= x0 && x1 <= ex && sy <= y0 && y1 <= ey) {
                    
            if(T[root].Max > Max)
                        Max 
            = T[root].Max;
                    
            return ;
                }


                
            int lmidx = (x0 + x1) >> 1;
                
            int lmidy = (y0 + y1) >> 1;
                
            int rmidx = (lmidx < x1) ? lmidx+1 : lmidx;
                
            int rmidy = (lmidy < y1) ? lmidy+1 : lmidy;

                Query(T[root].son[
            0], sx, ex, sy, ey, x0, lmidx, y0, lmidy, Max);
                Query(T[root].son[
            1], sx, ex, sy, ey, x0, lmidx, rmidy, y1, Max);
                Query(T[root].son[
            2], sx, ex, sy, ey, rmidx, x1, y0, lmidy, Max);
                Query(T[root].son[
            3], sx, ex, sy, ey, rmidx, x1, rmidy, y1, Max);
            }


            void Insert(int& root, int x, int y, int x0, int x1, int y0, int y1, int val) {
                
            if(x < x0 || x > x1 || y < y0 || y > y1)
                    
            return ;

                
            if(root == -1{
                    root 
            = Tree_Id++;
                    T[root].clear();
                }

                
            if(val > T[root].Max)
                    T[root].Max 
            = val;

                
            if(x0 == x && x == x1 && y0 == y && y == y1) {
                    
            return ;
                }

                
                
            int lmidx = (x0 + x1) >> 1;
                
            int lmidy = (y0 + y1) >> 1;
                
            int rmidx = (lmidx < x1) ? lmidx+1 : lmidx;
                
            int rmidy = (lmidy < y1) ? lmidy+1 : lmidy;
                
                Insert(T[root].son[
            0], x, y, x0, lmidx, y0, lmidy, val);
                Insert(T[root].son[
            1], x, y, x0, lmidx, rmidy, y1, val);
                Insert(T[root].son[
            2], x, y, rmidx, x1, y0, lmidy, val);
                Insert(T[root].son[
            3], x, y, rmidx, x1, rmidy, y1, val);
            }

            int n;
            int main() {
                
            int i;
                
            int MaxX, MaxY, MinX, MinY;
                
            while(scanf("%d"&n) != EOF && n) {
                    Rec.clear();
                    MaxX 
            = MaxY = INT_MIN;
                    MinX 
            = MinY = INT_MAX;

                    
            for(i = 0; i < n; i++{
                        
            int x0, x1, y0, y1;
                        scanf(
            "%d %d %d %d"&x0, &y0, &x1, &y1);
                        Rec.push_back(Rectangle(x0, x1, y0, y1));
                        MinX 
            = Min(x0, MinX); MinY = Min(y0, MinY);
                        MaxX 
            = Max(x1, MaxX); MaxY = Max(y1, MaxY);
                    }

                    MinX 
            -= 2; MinY -= 2; MaxX += 2; MaxY += 2;
                    sort(Rec.begin(), Rec.end(), cmp);
                    Tree_Id 
            = 0;
                    
            int ans = 1;
                    
            int root = -1;
                    
            for(i = 0; i < Rec.size(); i++{
                        
            int Max = 0;
                        Query(root, MinX, Rec[i].x0
            -1, MinY, Rec[i].y0-1, MinX, MaxX, MinY, MaxY, Max);
                        Insert(root, Rec[i].x1, Rec[i].y1, MinX, MaxX, MinY, MaxY, Max 
            + 1);
                        
            if(Max + 1 > ans)
                            ans 
            = Max + 1;
                    }

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

                
            return 0;
            }

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

            亚洲人成无码久久电影网站| 久久久久久亚洲精品成人| 日本欧美国产精品第一页久久| 亚洲日本va午夜中文字幕久久| 国产精品99久久久精品无码| 国产成人精品久久一区二区三区| 国产无套内射久久久国产| 日产精品99久久久久久| 久久久久国产视频电影| 奇米影视7777久久精品| 欧美久久久久久午夜精品| 久久久久AV综合网成人| 久久受www免费人成_看片中文| 97久久久精品综合88久久| 色99久久久久高潮综合影院| www.久久热.com| 漂亮人妻被黑人久久精品| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 国产福利电影一区二区三区久久久久成人精品综合 | 99国产欧美精品久久久蜜芽| 亚洲人成网站999久久久综合| 国产2021久久精品| 狠狠色丁香婷婷综合久久来 | 久久精品中文字幕第23页| 精品人妻久久久久久888| 五月丁香综合激情六月久久| 久久久久久久综合狠狠综合| 久久久受www免费人成| 亚洲成色999久久网站| 97热久久免费频精品99| www久久久天天com| 久久99精品国产麻豆| 欧美一区二区三区久久综| 久久综合给合久久国产免费| 国产成人精品久久| 久久亚洲欧美国产精品| 久久婷婷激情综合色综合俺也去| 亚洲αv久久久噜噜噜噜噜| 亚洲精品午夜国产VA久久成人| 99精品久久久久久久婷婷| 久久久国产精华液|