HDU 1542 線段樹 離散化 掃瞄線

2021-08-21 19:10:35 字數 1506 閱讀 5903

題意: 給你n個矩形的左上角頂點與右下角頂點, 求 n個矩形的面積和(可能重疊,重疊的部分只算一次)。

思路: 掃瞄線模版題。關於掃瞄線建議看這個部落格: 

還有乙個比較重要的問題,

一般的線段樹以及我們的區間修改合併,都有乙個共同點,就是不會出現區間缺失的現象,什麼叫區間缺失,顧名思義,區間缺失就是缺少一些區間沒有進行運算,這裡的掃瞄線就會遇到這個問題。

普遍的,我們的線段樹以及資料區間分布是這樣的:

[1, a][a + 1, b][b + 1, c][c + 1, d][d + 1, e].......

但是如果只是簡簡單單的用這個來解決掃瞄線的問題會導致錯誤,為什麼因為,他沒有涉及到[a,a + 1],在掃瞄線中會出現[a,a + 1]中的資料,而常用的線段樹的區間概念是無法解決這樣的問題的,出現了所謂的區間缺失,怎樣解決,下面的**給出了解決方案,這裡簡單的提一下,就是利用[ , ),這個區間性質,左閉右開,即可解決區間缺失問題

ac**:

#include#include#includeusing namespace std;

const int maxn = 210;

struct xx

xx(double l,double r,double h,int d):l(l),r(r),h(h),d(d){}

}line[maxn << 4];

double sum[maxn << 4]; ///存放投影

double x[maxn << 4]; ///存放所有的x座標

int cnt[maxn << 4]; ///cnt[i] != 0 說明 i代表的 這個區間 被覆蓋, == 0則未被覆蓋或未被完全覆蓋

///(對於乙個區間上下邊一定是成對出現,掃瞄線從下往上掃,途中cnt的值可能大於1,但一定不可能小於0)

bool cmp(xx a, xx b)

void pushup(int l,int r,int i)

void build(int l,int r,int i)

void update(int l,int r,int ul,int ur,int i,int key)else

}int main()

///離散化

sort(line + 1,line + pl,cmp);

sort(x + 1,x + pl);

int lisan = unique(x + 1,x + pl) - x - 1; ///此時 lisan 正好是去重後的最後乙個元素的下標

build(1,lisan, 1);

double ans = 0;

for(int i = 1;i < pl;i ++)

printf("test case #%d\n",k++);

printf("total explored area: %.2lf\n\n",ans);

}return 0;

}

hdu1542線段樹(掃瞄線 離散化)

題目鏈結 要求矩形的面積並 不複雜,主要要理解掃瞄線的思想以及一些細節的處理。首先需要將接收到的x座標離散化,方法就是排序去重。接下來的線段樹建立在這個 關於x座標的陣列上,這很關鍵。線段樹的節點代表一段區間,這個區間是由x座標陣列的下標 來構成的。更新的時候就根據水平線段的左右x座標獲得區間,然後...

HDU 1542 掃瞄線入門 線段樹離散化

掃瞄線演算法 線段樹維護簡介 像這種求面積的並集的題目,就適合用掃瞄線演算法解決,具體來說就是這樣 類似這種給出點的矩形的對角的點的座標,然後求出所有矩形面積的交集的問題,可以採用掃瞄線演算法解決。圖如下,我們要求紅色部分的面積 我們可以通過一條叫掃瞄線的東西解決問題。具體來說 我們首先給自己一條線...

hdu1542(線段樹 掃瞄線)

裸的掃瞄線,學習掃瞄線的題目。具體掃瞄線的原理我不講了,我是看大神們的部落格懂得,就算寫也沒大神屌。下面我給出我的 裡面的注釋是我認為比較重要的地方 include include include includeusing namespace std const int max 210 int n ...