Luogu P5490 模板 掃瞄線

2022-06-13 14:18:11 字數 1573 閱讀 1823

求 \(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...