1. 程式人生 > >POJ 2528 線段樹+離散化

POJ 2528 線段樹+離散化

//線段樹的建樹過程主要有兩種形式,一種形式是
//            [1,3]
//         [1,2] [2,3] 
//另外一種形式是
//             [1,3]
//           [1,2] [3,3]
//         [1,1] [2,2] 
//本文用的是第二種形式,因為有【1,1】這種形式的存在 
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
using namespace std;

int c,n,left,right;
int i,j;

struct Node
{
    int left,right;
    int cover;
};
//儲存線段樹 
Node tree[20005*4];
int reg[20005][2];
int dis[10000005];
int ep[20005];
int flag[10005];

//建立線段樹 
void build(int root,int l,int r){
    tree[root].left=l;
    tree[root].right=r;
    tree[root].cover=0;
    
    if(l==r)
        return;
    int mid=(l+r)>>1;
    build(root<<1,l,mid);
    build(root<<1|1,mid+1,r);
}
//向線段樹中插入區間(a,b)
void insert(int root,int a,int b,int col){
     if(b<tree[root].left||a>tree[root].right)
         return;
     if(a<=tree[root].left && b>=tree[root].right){
         tree[root].cover=col;
         return;
     }
     if(tree[root].cover>=0){
         tree[root*2].cover=tree[root*2+1].cover=tree[root].cover;
         tree[root].cover=-1;
     }
     insert(root*2,a,b,col);
     insert(root*2+1,a,b,col);
} 

void Count(int root,int l,int r){
    if(tree[root].cover>=0) flag[tree[root].cover]=1;
    else if(r-l>=1){
        Count(root*2,l,(l+r)>>1);
        Count(root*2+1,(l+r)>>1+1,r);
    }
}

int main(){
    scanf("%d",&c);
    while(c--){
        memset(dis,0,sizeof(dis));
        memset(flag,0,sizeof(flag));
        scanf("%d",&n);
        int p=0;
        for(i=1;i<=n;i++){
            scanf("%d%d",®[i][0],®[i][1]);
            if(dis[reg[i][0]]==0){
                //設定為訪問過,這個過程是為了去重 
                dis[reg[i][0]]=1;
                ep[++p]=reg[i][0];
            }
            if(dis[reg[i][1]]==0){
                dis[reg[i][1]]=1;
                ep[++p]=reg[i][1];
            }
        }
        //離散化 
        sort(ep+1,ep+1+p);
        int hash=0;
        for(i=1;i<=p;i++){
            dis[ep[i]]=++hash;
        }
        //建立線段樹 
        build(1,1,p);
        for(i=1;i<=n;i++){
            insert(1,dis[reg[i][0]],dis[reg[i][1]],i);
        }
        Count(1,1,p);
        int res=0;
        for(i=0;i<=n;i++)
            if(flag[i])
                res++;
        if(flag[0])
            printf("%d\n",res-1);
        else
            printf("%d\n",res);
    }
    return 0;
}

相關推薦

POJ 2528 線段 離散 逆向思維

要求:向長度為1e8的牆上貼最多1e4個長度不等的海報,每個海報貼在牆上任意位置,問最後能見到幾個海報(見到海報的一部分也算是見到該海報)。 方法:線段樹區間修改 離散化 逆向思維 1.建造一個1e8的線段樹必定TLE,因此需要離散化(壓縮區間)。 此題離散化具體步驟:先用ql陣列和qr

poj 2528 線段+離散

E - 成段更新 Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description The

POJ 2528 線段離散

[解題報告】 題目大意: 給定長度區間(L,R)//L,R<=1e7, 給出N個區間操作,把li-ri區間貼上海報 //N《=1e5 求:有多少張海報沒有被完全覆蓋 這道題目的關鍵在於,直接開1e7的線段樹一定會MLE,但我們觀察到一共只有不

POJ 2528 線段+離散

//線段樹的建樹過程主要有兩種形式,一種形式是 // [1,3] // [1,2] [2,3] //另外一種形式是 // [1,3] // [1,2] [3,3] // [1

POJ 2528 (線段 + 離散)

Mayor's posters Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been

poj 2528(線段+離散)

如圖,貼海報,後面的海報可以貼在前面的海報的上面,按給定的順序在區間為(l,r)的位置去貼海報,問最後可以在表面看見的海報有多少張 給定的區間範圍很大,為1 <= li <= ri <= 10000000 靜態的話,直接用線段樹進行區間更新,需要10

poj 2528 (線段+離散)

大致題意:     有一面牆,被等分為1QW份,一份的寬度為一個單位寬度。現在往牆上貼N張海報,每張海報的寬度是任意的,但是必定是單位寬度的整數倍,且<=1QW。後貼的海報若與先貼的海報有交集,後貼的海報必定會全部或區域性覆蓋先貼的海報。現在給出每張海報

POJ 3277 線段+離散

題意: 給定n個線段以及沒個線段上的高度,求最終所有線段的矩形面積並。 分析: 由於資料範圍較大,所以採用離散化,再用每個點進行建樹,之前沒這麼建過線段樹,學到了。 #include<cstdio> #include<algorithm> #i

2528 線段 + 離散

#include<iostream> #include<cstdio> #include<algorithm> #include<set> using namespace std; const int maxn = 1e5;

POJ 2528 Mayor's posters (線段 離散+區間更新+區間求值 )

href eof 求值 給定 一個點 一個 stream 問題 void 題目鏈接:http://poj.org/problem?id=2528 題意:塗色問題,給定n個要塗色的區間(每次用的顏色不一樣,顏色覆蓋性極強),問最後能看到多少種顏色。(貼海報問題轉換) 題解

poj 2528 線段+特殊離散

cto 1-1 there sync ali after hat tor memory Mayor‘s posters Time Limit: 1000MS Memory Limit: 65536K Total Submissions:

poj 2528 Mayor's posters(線段+離散)

The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at

POJ 2528 Mayor's posters(線段+離散

Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 60691 Accepted: 17565 Description The citizens of Byteto

線段 + 離散 + 詳細註釋】北大 poj 2528 Mayor's posters

/* THE PROGRAM IS MADE BY PYY */ /*----------------------------------------------------------------------------// Copyright (c) 2011 panyanyany All rig

POJ 2528 Mayor's posters (線段+離散 成段替換)

題目大意: 就是在一段區間上貼海報, 後來的區間會把前面來的區間覆蓋掉, 為貼完海報後能看到幾張海報(只看到一部分也算看到) 大致思路: 就是區間替換更新, 標記一下當前區間的所有的海報是否一致, 用懶惰標記標記一下當前區間的類別 聽說資料比較水...布吉島嚴格的資料下這

POJ 2528 經典!線段離散

http://poj.org/problem?id=2528 題意:n(n<=10000)個人依次貼海報,給出每張海報所貼的範圍li,ri(1<=li<=ri<=10000000)。求出最後還能看見多少張海報。 解法:離散化,如下面的例子(題

線段+離散操作(poj 2528)

#include<iostream> #include<cstdio> #include<algorithm> #define Pn 10005 #define MAXN 1000005 using namespace std; int tN,pN; struct Tnod

POJ 2482】 Stars in Your Window(線段+離散+掃描線)

d+ opera algorithm ans som lov ble word wait 【POJ 2482】 Stars in Your Window(線段樹+離散化+掃描線) Time Limit: 1000MS M

POJ 1151 Atlantis 線段+離散

roc 線段樹 aps sin program cal ase gree org 題目鏈接:http://poj.org/problem?id=1151 http://acm.hdu.edu.cn/showproblem.php?pid=1542 題目大意:給你幾個矩形的

N - Picture POJ - 1177(矩形周長並 + 線段 + 離散

本程式碼採用的是橫向掃描一遍和縱向掃描一遍來得到最終的結果,核心部分就是求舉行周長並,當然也要對線段樹比較熟悉才行,畢竟矩形周長並,面積並,面積交都要用到線段樹來計算。說說求舉行周長並的過程吧,我們先計算橫向線段的長度,把所有座標的y軸座標按照升序排列,掃描線從y的最小值依次向上掃描,求出每