P5490 模板 掃瞄線

2022-09-28 04:12:11 字數 1475 閱讀 1052

掃瞄線的過程不做多述

主要講解**實現,沒有深刻理解是無法完全打出來的

首先離散化x座標,因為我們要用線段樹進行維護,x座標過大,陣列範圍是不允許的

再考慮線段樹怎麼維護

假如維護k[1,3]--->兩個子節點k1[1,2],k2[3,3]

假如k1的len=x[2]-x[1]

那k2的len=x[3]-x[3]

k2此時為乙個點了,明顯不符合

所以我們設維護k[l,r],維護的是乙個區間[l,r+1]

這樣就巧妙地解決了

因為每次我們要查詢1號節點的總長度,所以我們有個pushup操作,懶標記就不用pushdown

code by std

#include #include #include #define lson (x << 1)

#define rson (x << 1 | 1)

using namespace std;

const int maxn = 1e6 + 10;

typedef long long ll;

int n, cnt = 0;

ll x1, y1, x2, y2, x[maxn << 1];

struct scanline

} line[maxn << 1];

struct segtree tree[maxn << 2];

void build_tree(int x, int l, int r)

void pushup(int x)

void edit_tree(int x, ll l, ll r, int c)

edit_tree(lson, l, r, c);

edit_tree(rson, l, r, c);

pushup(x);

}int main() ;

line[2 * i] = (scanline) ;

// 一條線段含兩個端點,乙個矩形的上下邊都需要掃瞄線掃過

} n <<= 1;

// 直接把 n <<= 1 方便操作

sort(line + 1, line + n + 1);

sort(x + 1, x + n + 1);

int tot = unique(x + 1, x + n + 1) - x - 1;

// 去重最簡單的方法:使用unique!(在庫中)

build_tree(1, 1, tot - 1);

// 為什麼是 tot - 1 :

// 因為右端點的對應關係已經被篡改了嘛…

// [1, tot - 1]描述的就是[x[1], x[tot]]

ll ans = 0;

for(int i = 1; i < n /* 最後一條邊是不用管的 */ ; i++)

printf("%lli", 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 ...

線段樹 掃瞄線 P5490 模板 掃瞄線

首先有這麼一張圖,要求它的面積並。我們想,如果可以有一條掃瞄線從下往上掃,記錄它所掃到的邊的長度 並 len 再求出這條邊與即將掃到的下一條邊的距離 h 那麼我們就可以求出第一塊面積 紫色 s 1 len times h 然而如何求出這個 len 顯然只用當前邊的長度是不行的,如 當掃到邊 r 2 ...