聽說掃瞄線很牛掰,於是就見識了一下。
之前做過一道掃瞄線的題,brother,就是判斷矩形是否被矩形內部的車攻擊到。當時是把矩形拆成出邊和入邊(豎直的),把所有小於x2的車加進圖中,掃[y1,y2]中x最小的車的x.和x1判斷比較。然後交換x,y掃一遍
當時只是感覺線段樹很神奇,還可以這樣搞,後來才知道這種按x2的排序遍歷就相當於掃瞄線。
然後就做了掃瞄線的入門題。
weird advertisement
uva - 11983
一道掃瞄線矩形面積並,求被覆蓋k次的矩形面積(雖然是點,不過x2+1,y2+1就變成了求面積。 比如只有乙個點,把它x2+1,y2+1,就變成了面積為1的正方形)。
理解了大致思路,套了個版.
下面解決一下大致思路吧。
把矩形拆成入邊和出邊,記錄下來,還要打上出入邊標記。
按x排序(我是按x拆的,兩條邊x不同,豎直),然後掃到入邊,把[y1,y2]加入,否則把[y1,y2]減去。
要更新》=k的次數。
其實主要複雜一點的是pushup.
一般需要離散化,因為題目往往不會很簡單
覆蓋k次矩形面積並
#include#include#include#include#include#include#include#define ll long long
using namespace std;
ll n,k;
const ll maxn=30000+20;
struct line
bool operator<(const line &p)const
struct node
}t[8*maxn];
void pushup(ll u)
else }
}void build(ll i,ll l,ll r)
ll mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
pushup(i);
}void updata(ll i,ll l,ll r,ll x)
ll mid=(l+r)>>1;
if(l<=mid)updata(i<<1,l,r,x);
if(r>mid)updata(i<<1|1,l,r,x);
pushup(i);
}int main()
sort(l.begin(),l.end());
sort(det+1,det+tot+1);
ll t=tot;
tot=unique(det+1,det+t+1)-det-1;
build(1,1,tot);
ll ans=0;
for(ll i=0;i
這是最裸的矩形面積並。
#include#include#include#include#include#include#include#include#define ll long long
using namespace std;
ll n;
const ll maxn=100000+20;
const ll k=1;
struct line
bool operator<(const line&p)const
struct node
}t[8*maxn];
void pushup(ll i)
else
}}void build(ll i,ll l,ll r)
ll mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
pushup(i);
}void updata(ll i,ll l,ll r,ll x)
ll mid=(l+r)>>1;
if(l<=mid)updata(i<<1,l,r,x);
if(r>mid)updata(i<<1|1,l,r,x);
pushup(i);
}int main()
sort(det+1,det+tot+1);
sort(l.begin(),l.end());
ll t=tot;
tot=unique(det+1,det+t+1)-det-1;
build(1,1,tot);
ll ans=0;
for(ll i=0;i
掃瞄線大致是一種思想,用資料結構維護。
P5490 模板 掃瞄線 掃瞄線
題目描述 求 n 個矩形的面積並。輸出格式 一行乙個正整數,表示 n 個矩形的並集覆蓋的總面積。発生 線段樹開小了,因為n變成了兩倍,線段樹就得開4 2 8倍 對每一根掃瞄線,維護所截得的長度,每次乘以兩根掃瞄線高度差就得到了面積並 截得長度用線段樹維護即可 注意線段樹需要離散化 include i...
模板 掃瞄線
矩形有重疊,求總面積。橫縱兩條掃瞄線 includeusing namespace std double x 2002 y 2002 最多100個矩形,所以最多只有200條橫線或縱線 double a 1002 4 矩形實際座標,分別是左下角橫 縱,右下角橫 縱 bool cover 2002 20...
掃瞄線學習
對掃瞄線步驟的理解 1 首先要儲存所有的邊,並按照x值從小到大排序,如果是左邊,標記為1,如果是右邊,標記為 1。struct line 2 掃瞄線從左往右掃瞄,每遇到一條邊就停下來,將這條邊投影到總區間上,投影 其實就是執行在總區間中插入或者刪除線段操作。掃瞄到flag為1的邊,為左邊,往總區間加...