hdu 1542 掃瞄線 線段樹求矩陣面積並

2021-07-04 06:36:01 字數 1286 閱讀 9420

這幾天想啃啃樹,無意中找到了這個題,一方面練習一下線段樹,另一方面學習一下離散化和掃瞄線的技巧。

首先,離散化是必要的,因為x,y<=100000顯然我們無法通過遍歷每個點的方式來得到矩形面積。所以我們必須要對點進行離散化的處理。簡單的講離散化就是把一組資料存入陣列中,並且用陣列的下標代替這組資料。

顯然,離散化的資料不會有重複,這裡要介紹乙個函式unique,如果現在有乙個長度為n的陣列unique(a,a+n)返回乙個迭代器(也就是指標),它的作用是將a陣列中相同的元素都只出現一次,unique(a,a+n)-a就是a中不相同元素的個數。值得一提的是,unique雖然使陣列元素都不相同,但它並不刪除元素,只是將相同的元素移動到陣列的末尾。

接下來,我們介紹掃瞄線的概念。假想現在有一條掃瞄線,從左向右(或者從右向左)或者從下到上(或從上到下)的掃過座標平面。我這裡假設掃瞄線從下向上掃過(其它方向類似)。如果掃瞄線從下向上掃過的話,我們要離散橫座標,並且記錄矩陣和橫座標平行的兩條線段,之所以是兩條是由於一條是矩陣的上底邊,一條是矩陣的下底邊,我們對矩陣的下底邊賦乙個特徵值1,對上底邊賦乙個特徵值-1。然後掃瞄線從下向上掃過,當這條掃瞄線掃過一條線段的時候,我們將這條線段投影到x軸上,就變成了x軸上求覆蓋區間長度的問題,我們將x軸上相應的區間加上相應的特徵值1或-1,如果區間特徵值是0則表示區間未被覆蓋,大於0則表示區間已被覆蓋,不可能會出現小於0的情況(因為每個-1出現之前一定會出現乙個1),這個時候我們就需要用到線段樹了(其實對於這個題我覺得直接暴力也可以的,不需要線段樹也可以做,不過我沒試)。然後被覆蓋的線段就是目前的底邊,將它乘以相應的高就可以了。

如果用線段樹做區間的覆蓋的話,我這裡是用的區間樹,我看了看網上的解題報告,他們都是用的點樹,我沒太看懂qaq,我覺得區間樹更直白一點。

下面是**:

#include #include #include using namespace std;

struct node

;node a[2005];

int n,m,k=0;

int mark[1005],lt[1005],rt[1005];

double lisan[2005],s[1005];

bool cmp(node a,node b)

void init()

update(k);

}int main()

k++;

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

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

}return 0;

}

hdu1542(線段樹 掃瞄線)

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

hdu 1542 掃瞄線 線段樹

題目大意 求矩形面積的並 思路 按y軸排序,然後將x投影到線段樹上做乙個線段覆蓋問題即可 注意 為了避免重複,線段座標右端點是開區間,更新時需要加上1 include include include include include define fo i,a,b for int i a i b i ...

hdu1542(線段樹 掃瞄線)

題目連線 又看到了幾個月前做的題,感覺那時候就是個sb 也怪自己剛開始沒搞清楚線段樹,瞎摸索 用連續線段樹很好理解這個題,之前的 稍微改了一下就好理解多了 1 include2 include3 include4 define lson l,m,rt 1 5 define rson m,r,rt 1...