題意:在1-10^7的長度上貼海報,求能看到的海報數目
解題思路:10^7無論用樸素法或線段樹解都會超時超記憶體,所以要進行離散化。所謂離散化就是把有限的個體對映到有限的空間,以此提高演算法的時空效率以這題的測試資料為例,本題的五個區間為1 4,2 6,8 10,3 4,7 10;其中10和4出現了兩次,把重複的數字去除,然後排序得1 ,2,3,4,6,7,8,10,與之對應的陣列下標為1 2 3 4 5 6 7 8,以陣列下標區間邊界得到新的五個區間為[1,4],[2,5],[7,8],[3,4],[6,8].有題目知每次區間最多給10000個,那麼線段樹的n = 20000.接下來就用線段樹的成段更新就可以了,這裡不用資訊的維護
離散化的一些注意事項:
1、有n個數字ai,n一般小於10^6 ,而這些數字的範圍卻很大,比如 0 <= ai <= 1,000,000,000 , 先在按我們的思路要把ai當做下標
這時候要用離散化
2、ai 中沒有相同的數字
如poj2299和poj2528
**如下:
#include#include#include#include#include#include#include#include#include#include#include#include#define n 20000 + 5
#define inf 0x7fffffff
#define eps 1e-9
#define pi acos(-1.0)
#define p system("pause")
using namespace std;
int x,y;
setq;
struct node
s[2*n];
bool cmp (node a,node b)
void pushdown(int o)
}void update(int o,int l,int r,int k)
else
}void query(int o,int l,int r)
if(l == r) return;
int m = (l+r)/2;
query(2*o,l,m);
query(2*o+1,m+1,r);
}int main()
sort(s,s+2*n,cmp);
int k = 1;
if(s[0].bor < 0)
else
for(i = 1; i < 2*n; i++)
// for(i = 0; i < n; i++)
for(i = 0; i < n; i++)//線段樹成段更新
q.clear();
query(1,1,k);
printf("%d\n",q.size());
}return 0;}/*
151 42 6
8 10
3 47 10
*/
POJ2528 離散化線段樹
將資料離散化在使用線段樹 有一面牆,被等分為1qw份,乙份的寬度為乙個單位寬度。現在往牆上貼n張海報,每張海報的寬度是任意的,但是必定是單位寬度的整數倍,且 1qw。後貼的海報若與先貼的海報有交集,後貼的海報必定會全部或區域性覆蓋先貼的海報。現在給出每張海報所貼的位置 左端位置和右端位置 問張貼完n...
poj 2528 線段樹 離散化
題目連線 題目大意 在一面牆上貼海報,牆很長,後面貼上去的海報要覆蓋掉之前貼上去的海報,現在向牆上逐一的貼海報,問到最後牆上可以看見的海報有幾種?方法 線段樹,離散化 include include include include using namespace std define maxn 10...
poj 2528 離散化 線段樹
這個破題 我wa 了 我實在找不到我那裡錯了 題意 有乙個牆,往牆上貼報紙,最後問能看到幾張報紙 其實就是很容易的線段樹,不容易的地方在於離散化 離散化要儲存所有需要用到的值,排序後,分別對映到1 n,這樣複雜度就會小很多很多這題的難點在於每個數字其實表示的是乙個單位長度 並且乙個點 這樣普通的離散...