求 \(n\) 個矩形的面積並。
本題計算面積並在掃瞄線中較為簡單。拋開離散化,我們著重講掃瞄線。
與上圖為例,思考怎麼計算它們的幾何並。
用乙個陣列來存資訊,覆蓋了就標 1,否則標 0。暴力既好想又好寫,但當座標一大,時空都會超。
用總面積減去重合面積。但只侷限於重合少的題。
將圖形重新分割成乙個個規則的矩形,用線段樹維護一條掃瞄的線。
如上圖,每掃瞄到一段,該段面積就是直線上覆蓋的長度乘該段的寬度。
順著這個思路來,用乙個四元組 \((x,y_1,y_2,flag)\) 記錄每一條豎線,表示豎線的座標及是否是左右邊界。
線段樹維護掃瞄線上被覆蓋的長度,每次修改後,更新被覆蓋長度(如下)。
void pushup(int x)
對於線段樹任意乙個節點 \([l,r]\),若 \(cnt>0\),則 \(len\) 就等於兩子節點 \(len\) 之和。在乙個節點 \(cnt\) 被修改,以及線段樹傳遞資訊時,我們都按照方法更新 \(len\) 值。根節點 \(len\) 值就是整個掃瞄線被覆蓋的長度。
const int n = 2000000 + 10;
int n;
struct segmenttree
t[n << 2];
ll x[n], disx[n], y[n];
struct node
a[n << 2];
bool cmp(node a, node b)
void build(int x, int l, int r)
void pushup(int x)
void change(int x, int l, int r, ll k)
int mid = (t[x].l + t[x].r) / 2;
if(l <= mid) change(x * 2, l, r, k);
if(r > mid) change(x * 2 + 1, l, r, k);
pushup(x);
}ll ans;
int main()
sort(x + 1, x + 1 + m);
m = unique(x + 1, x + 1 + m) - (x + 1);
for (int i = 1; i <= n * 2; i++)
m = 2 * n;
build(1, 1, m);
sort(a + 1, a + 1 + m, cmp);
for (int i = 1; i <= m; i++)
printf("%lld\n", ans);
return 0;
}
P5490 模板 掃瞄線 掃瞄線
題目描述 求 n 個矩形的面積並。輸出格式 一行乙個正整數,表示 n 個矩形的並集覆蓋的總面積。発生 線段樹開小了,因為n變成了兩倍,線段樹就得開4 2 8倍 對每一根掃瞄線,維護所截得的長度,每次乘以兩根掃瞄線高度差就得到了面積並 截得長度用線段樹維護即可 注意線段樹需要離散化 include i...
P5490 模板 掃瞄線
n 給定n nn個矩形左下角和右上角的座標,求該矩形面積並 資料範圍 n 1 05n leq 10 5 n 105sol utio nsolution soluti on將每個矩形看做兩條平行於y yy軸的線段,掃瞄過去即可 需要注意的是給出來的是點,而我們維護的是線段 時間複雜度 o n log ...
Luogu5490 模板 掃瞄線
根據橫座標或縱座標排序另一方向的線段,進入的賦值 1 離開的賦值 1 注意一下,線段樹的構造中,乙個位置表示的是乙個間隔,即 a 1 表示間隔 1,2 間隔個數為點的個數 1 如果用點來建,乙個點根本無法計算貢獻 c code include include include define ll lo...