理解 線段樹 掃瞄線

2021-07-10 01:22:43 字數 1540 閱讀 2520

題目大意: 給你n個矩形,求他們的總面積之和。

解題思路:

哈哈,不過大家別急,為了方便描述,自己動手畫了幾個。

四條紅線為矩形的上下底邊,這裡我們稱之為掃瞄線(實際程式設計中不存在,只是乙個概念)。

如圖所示,要求兩個矩形的面積並,可以把矩形分成幾個小矩形,最後的面積總和為它們的和。

對於每個小矩形其 面積s=長*寬。寬就是兩條掃瞄線之間y的差值,這裡留給我們的問題就是如何求長了。

因為x是double型而且比較大,所以首先對x進行離散化,x陣列下標對應實際的x。

然後就開始建樹了,建樹比較簡單,主要的問題在於如何進行更新樹。我在這裡卡了好久,要注意實際的掃瞄線長度隨時可能變化,並不是相同的,唯一不變的就行要更新數的左右區間(即矩形的底邊長度)。

因為掃瞄線是會變的,所以這裡才是我們要重點解決的問題,怎麼辦?哈哈,這裡引出我們偉大的標記變數cover, 對於每個矩形下底邊標記為1,上底邊標記為-1。當一根線掃瞄到下一根線的時候,cover值會覆蓋相應的區間,被覆蓋的區間flag值會加上此掃瞄線的cover(可能為正也可能為負)值,這裡最好動手自己模擬一下。所以重疊位置(flag>2)就算遇見負的cover它的flag依然是正的!!

重點要提的是:覆蓋區間只在總區間上變化,總區間一直保持不變。   

ps: 還是看不懂的話看著**理解吧,我就是這樣過來的。

對掃瞄線進行y從小到大排序,然後從下往上掃瞄。

#include #include #include #include using namespace std;

#define lz 2*u,l,mid

#define rz 2*u+1,mid+1,r

const int maxn=4222;

double sum[maxn];

int flag[maxn];

double x[maxn];

struct node

; node(double lx_, double rx_, double y_, int s_)

bool operator

push_up(u,l,r);

}int main()

sort(x+1,x+num+1);

sort(line+1,line+num+1);

int k=1;

for(int i=2; i<=num; i++)

if(x[i]!=x[i+1]) x[++k]=x[i];

double ans=0;

for(int i=1; i

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

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

}return 0;

}

線段樹 掃瞄線

pku 1151 hdu1542 atlantis 矩形面積並 題意 給出n個矩形,每個矩形給出左下角座標,右上角座標。然後求矩形並的總面積 思路 浮點數先要離散化 然後把矩形分成兩條邊,上邊和下邊,對橫軸建樹,然後從下到上掃瞄上去,用cnt表示該區間下邊比上邊多幾個,sum代表該區間內被覆蓋的線段...

掃瞄線 線段樹

問題描述 小明的家旁邊有條河流,但最近,周圍的三個工廠開始向這條河排放汙水,這條河的一部分被汙染了,被乙個工廠汙染的部分可以看做乙個矩形,現在小明想知道這條河被汙染的面積是多少。輸入 第一行乙個整數t,表示有多少組資料,之後每一組資料報括三行,每一行有lx,ly,rx,ry四個整數,表示被乙個工廠汙...

線段樹 掃瞄線

掃瞄線問題主要利用了線段樹。因為矩形的並集比較難算,所以我們可以用 sum 掃瞄線被截長度 所掃瞄的高度 來求和。而這樣做發現可以用線段樹來優化,具體優化方式如下 所掃瞄的高度比較好求,主要是掃瞄線被截長度需要優化。我們可以設橫邊有乙個a權值,如果該邊是矩陣的下邊則設為1,相反就設為 1,這樣如果一...