解題思路:
這道題目的意思是想讓我們去計算由許多矩形組成的多邊形的總面積,並且給出的座標可是浮點型的;對於這樣有對稱的線段出現並需要所框住區域中的某種屬性的量,其實都是可以使用掃瞄線(但是還是得說應用的領域不大);但是在使用掃瞄線去計算其的面積的時候,需要去統計乙個邊的長度,這時候用線段樹就會顯得非常的巧,因為每對邊都是成對出現的,所以省去了pushdown的操作,只需要乙個pushup操作就可以完成了。
所以這道題目的思路是:首先對其座標進行離散化,然後取出每個矩形的兩天邊放到vector容器中進行離散化;然後,將兩條邊分別賦予乙個屬性c來表示這條邊是需要加進去還是拿出來。最後對其x進行排序,然後不斷地去查詢線段樹中第乙個節點的len即可計算面積。
但是在寫**的過程紅也有一些需要注意的地方;首先,線段樹中的每乙個點其實存的是這個點所對應的那條邊,即:i 表示 i 到 i + 1.所以有兩個地方需要注意,乙個是build的時候,乙個是通過find去找l與r的時候,注意都需要多減去乙個1.
貼上(蒟蒻)**乙份
:
#include
#include
#include
#include
using
namespace std;
const
int maxn =
200005
;int n;
struct ********
}********[maxn]
;struct treement tr[
4* maxn]
;vector<
double
> ve;
inline
intfind
(double x)
inline
void
pushup
(int u)
else tr[u]
.len =0;
}inline
void
build
(int u,
int l,
int r);if
(l != r)
}inline
void
modify
(int u,
int l,
int r,
int c)
int mid = tr[u]
.l + tr[u]
.r >>1;
if(l <= mid)
modify
(u <<
1, l, r, c);if
(r > mid)
modify
(u <<1|
1, l, r, c)
;pushup
(u);
}int
main
(void);
********[j ++]=
; ve.
push_back
(y1)
, ve.
push_back
(y2);}
// puts("33");
sort
(ve.
begin()
, ve.
end())
; ve.
erase
(unique
(ve.
begin()
, ve.
end())
, ve.
end())
;build(1
,0, ve.
size()
-2);
//由於在這個線段樹中,每個節點所代表的是乙個線段,而不是乙個點,
//所以這裡需要在原來的基礎上再 減去乙個1;即:i:i - i + 1
sort
(********, ******** +
2* n)
;double fi =0;
double x1 =
0, x2 =0;
for(
int i =
0; i <
2* n; i ++
)printf
("test case #%d\ntotal explored area: %.2lf\n\n"
,++ count, fi);}
return0;
}
總結:要注意細節,尤其是對線段樹每個節點所代表的的含義要牢記。 AcWing247亞特蘭蒂斯(線段樹 掃瞄線)
題目位址 題目描述 有幾個古希臘書籍中包含了對傳說中的亞特蘭蒂斯島的描述。其中一些甚至包括島嶼部分地圖。但不幸的是,這些地圖描述了亞特蘭蒂斯的不同區域。您的朋友bill必須知道地圖的總面積。你自告奮勇寫了乙個計算這個總面積的程式。輸入格式 輸入包含多組測試用例。對於每組測試用例,第一行包含整數n,表...
線段樹 掃瞄線
pku 1151 hdu1542 atlantis 矩形面積並 題意 給出n個矩形,每個矩形給出左下角座標,右上角座標。然後求矩形並的總面積 思路 浮點數先要離散化 然後把矩形分成兩條邊,上邊和下邊,對橫軸建樹,然後從下到上掃瞄上去,用cnt表示該區間下邊比上邊多幾個,sum代表該區間內被覆蓋的線段...
掃瞄線 線段樹
問題描述 小明的家旁邊有條河流,但最近,周圍的三個工廠開始向這條河排放汙水,這條河的一部分被汙染了,被乙個工廠汙染的部分可以看做乙個矩形,現在小明想知道這條河被汙染的面積是多少。輸入 第一行乙個整數t,表示有多少組資料,之後每一組資料報括三行,每一行有lx,ly,rx,ry四個整數,表示被乙個工廠汙...