POJ 2528 線段樹離散化
[解題報告】
題目大意:
給定長度區間(L,R)//L,R<=1e7,
給出N個區間操作,把li-ri區間貼上海報 //N《=1e5
求:有多少張海報沒有被完全覆蓋
這道題目的關鍵在於,直接開1e7的線段樹一定會MLE,但我們觀察到一共只有不超過1e5張海報,如果每張海報我們只取它的兩個端點,只對它的端點進行處理,空間複雜度就會大大降低。
所以如何處理呢?
比如區間[1,4],[5,6]有四個不同端點,說明我們需要把他對映到線段樹上四個不同的位置。
我們從1開始對線段樹的葉子節點進行標記,那麼對映到的相對應的線段樹區間為:
[1,4]->[1,2]
[5,6]->[3,4]
這時候出現一個問題:
我們先後貼上[1,10],[1,4],[5,10],對映為:[1,4],[1,2],[3,4]只能看見兩張海報
如果先後貼上[1,10],[1,4],[7,10],對映為:[1,4],[1,2],[3,4],只能看見兩張海報。
哪裡出了問題?
問題在於:
如果兩條相鄰線段並不相交,離散化之後,它變成了相交!
所以維護這樣的性質:如果兩個頂點並不緊鄰,那麼我們離散化之後,它們仍然不能緊鄰。方法是在兩個頂點之間再插入一個頂點。
到了這裡,大部分問題就解決了。
還需要思考一個問題:如何查詢沒有被完全覆蓋的海報的數目。
容易想到,我們更新的時候,給區間(l,r)打上標記i表示當前位置的海報是i,這樣最後統計有多少個不同的i即可。
為了不重複查詢相同的,沒有被完全覆蓋的i,如: (1,10),( 3,4 ),(7,8)更新之後的標記就是1,2,1,3,1,會出現多個第1張海報的標記,我們需要單獨設定一個hash陣列,如果某張海報已經被統計過了,就不再重複統計。
這樣,剩下的就是線段樹模板的內容了。
剩下的細節可以參考程式碼。我的線段樹風格參考劉汝佳的《訓練指南》。
【參考程式碼】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+50;
int N,m,cnt;
int l[maxn],r[maxn],vis[maxn],X[maxn];
int cover[maxn*4];
void uniq( int nn )
{
m=0;
X[++m]=X[1];
for( int i=2; i<=nn; i++ )
{
if( X[i]!=X[i-1 ] )X[++m]=X[i];
}
sort( X+1,X+1+m );
int t=m;
for( int i=1;i<t;i++ )
{
if( X[i]!=X[i+1]-1 )X[++m]=X[i]+1;
}
sort( X+1,X+1+m );
}
void build( int O, int L, int R )
{
if(L==R)cover[O]=-1;
else
{
int mid=(L+R)/2;
build(O*2+1,mid+1,R );
build( O*2,L,mid );
cover[O]=-1;
}
}
void pushdown( int O )
{
if( cover[O]!=-1 )
{
cover[O*2]=cover[O*2+1]=cover[O];
cover[O]=-1;
}
}
void update( int O, int L, int R, int qL, int qR, int c )
{
if( qL<=L && R<=qR )
{
cover[O]=c;
}
else
{
pushdown( O );
int mid=(L+R)/2;
if( qL<=mid )update( O*2,L,mid, qL,qR,c );
if( qR>mid )update( O*2+1, mid+1,R,qL,qR,c );
}
}
void query( int O, int L, int R )
{
if( L==R )
{
if( cover[O]!=-1 && !vis[cover[O]] )
{
vis[cover[O]]=1;
cnt++;
}
}
else
{
pushdown(O);
int mid=(L+R)/2;
query( O*2, L,mid );
query( O*2+1,mid+1,R );
}
}
int main()
{
//freopen("2528","r",stdin);
int T; cin>>T;
while(T--)
{
scanf( "%d",&N );
int nn=0;
for( int i=1; i<=N; i++ )
{
scanf( "%d%d",&l[i],&r[i] );
X[++nn]=l[i]; X[++nn]=r[i];
}
sort( X+1,X+1+nn );
uniq(nn);
build( 1,1,m );
for( int i=1; i<=N; i++ )
{
int left=lower_bound( X+1,X+1+m,l[i] )-X;
int right=lower_bound( X+1,X+1+m,r[i] )-X;
update( 1,1,m,left,right,i );
}
memset( vis,0,sizeof vis );
cnt=0;
query( 1,1,m );
printf( "%d\n",cnt );
}
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的最小值依次向上掃描,求出每