原本想虐虐藍橋尋找一下快感,結果隨意選了一道題就是二分+掃瞄線…於是就滾回去補掃秒線了…(我太菜了)
下面以hdu-1542做例子寫的乙個板子
掃瞄線的思想很簡單放個圖應該就不會忘了:
掃瞄線所構造的線段樹葉子結點管轄的是乙個區間,為了避免以後腦子犯渾,我還是線段樹的構造也寫一下吧…
把y座標離散:
int num =1;
for(
int i =
2; i <= n; i++
)
建樹:
void
build
(int l,
int r,
int now)
更新:
void
pushup
(int now)
if(tree[now]
.l +
1== tree[now]
.r) tree[now]
.len =0;
else
tree[now]
.len = tree[now <<1]
.len + tree[now <<1|
1].len;
}void
update
(double l,
double r,
int v,
int now)
if(l >= tree[now <<1|
1].rl)
update
(l, r, v, now <<1|
1);else
if(r <= tree[now <<1]
.rr)
update
(l, r, v, now <<1)
;else
pushup
(now)
;}
getans:
double ans =0;
for(
int i =
1; i < n; i++
)
完整**:(水一下長度我很開心 >_
#include
#include
#include
#include
#define max 100010
using
namespace std;
struct node
}tree[max]
;//這裡不嚴謹,因為我max習慣的開的太大了...所以這裡沒有乘4/8
struct line
friend
intoperator
<
(line a,line b)
//sort會方便一點,感覺和cmp一樣...
}line[
300]
;//開2*n即可
double y[max]
;//同樣的2*n
void
build
(int l,
int r,
int now)
void
pushup
(int now)
if(tree[now]
.l +
1== tree[now]
.r) tree[now]
.len =0;
else
tree[now]
.len = tree[now <<1]
.len + tree[now <<1|
1].len;
}void
update
(double l,
double r,
int v,
int now)
if(l >= tree[now <<1|
1].rl)
update
(l, r, v, now <<1|
1);else
if(r <= tree[now <<1]
.rr)
update
(l, r, v, now <<1)
;else
pushup
(now);}
void
init()
intmain()
n *=2
;sort
(y +
1, y + n +1)
;int num =1;
for(
int i =
2; i <= n; i++
)sort
(line +
1, line + n +1)
;build(1
, num,1)
;double ans =0;
for(
int i =
1; i < n; i++)
cout <<
"test case #"
<< len++
<< endl;
cout <<
"total explored area: "
;printf
("%.2lf\n\n"
, ans);}
return0;
}
P5490 模板 掃瞄線 掃瞄線
題目描述 求 n 個矩形的面積並。輸出格式 一行乙個正整數,表示 n 個矩形的並集覆蓋的總面積。発生 線段樹開小了,因為n變成了兩倍,線段樹就得開4 2 8倍 對每一根掃瞄線,維護所截得的長度,每次乘以兩根掃瞄線高度差就得到了面積並 截得長度用線段樹維護即可 注意線段樹需要離散化 include i...
掃瞄線入門
聽說掃瞄線很牛掰,於是就見識了一下。之前做過一道掃瞄線的題,brother,就是判斷矩形是否被矩形內部的車攻擊到。當時是把矩形拆成出邊和入邊 豎直的 把所有小於x2的車加進圖中,掃 y1,y2 中x最小的車的x.和x1判斷比較。然後交換x,y掃一遍 當時只是感覺線段樹很神奇,還可以這樣搞,後來才知道...
模板 掃瞄線
矩形有重疊,求總面積。橫縱兩條掃瞄線 includeusing namespace std double x 2002 y 2002 最多100個矩形,所以最多只有200條橫線或縱線 double a 1002 4 矩形實際座標,分別是左下角橫 縱,右下角橫 縱 bool cover 2002 20...