線段樹 掃瞄線

2021-09-08 21:50:49 字數 3890 閱讀 5084

pku 1151 && hdu1542  atlantis  矩形面積並

題意:給出n個矩形,每個矩形給出左下角座標,右上角座標。然後求矩形並的總面積;

思路:浮點數先要離散化;然後把矩形分成兩條邊,上邊和下邊,對橫軸建樹,然後從下到上掃瞄上去,用cnt表示該區間下邊比上邊多幾個,sum代表該區間內被覆蓋的線段的長度總和

這裡線段樹的乙個結點並非是線段的乙個端點,而是該端點和下乙個端點間的線段,所以題目中r+1,r-1的地方可以自己好好的琢磨一下;

這裡點到線段的轉化不好理解:

我們的線段樹的葉子節點表示的是線段,座椅如果我們求1到4的線段長度是實際上是求的1,2,3好線段,所以r要-1,而當我們真正求長度是是x[i + 1] - x[i]才是i線段的長度。

#include #include 

#include

#include

#include

#include

#include

#include

#include

#include

#define cl(a,num) memset((a),(num),sizeof(a))

#define iabs(x) ((x) > 0 ? (x) : -(x))

#define min(a , b) ((a) < (b) ? (a) : (b))

#define max(a , b) ((a) > (b) ? (a) : (b))

#define ll __int64

#define inf 0x7f7f7f7f

#define mod 100000007

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define test puts("")

#define maxn 100007

#define m 100007

#define n 227

using

namespace

std;

//freopen("din.txt","r",stdin);

struct

seg seg(

double l,double r,double h,int

mk)

bool

operator

< (const seg &tmp) const

}seg[n];

int cnt[n<<2

];double sum[n<<2

],x[n];

void pushup(int rt,int l,int

r)void update(int l,int r,int sc,int l,int r,int

rt)

int m = (l + r)>>1

;

if (l <=m) update(l,r,sc,lc);

if (m

pushup(rt,l,r);}//

離散化後二分查詢

int bsearch(double val,int

n)

returnl;}

intmain()

//離散化

sort(x,x +len);

sort(seg,seg +len);

int k = 1

;

for (i = 1; i < len; ++i)

//線段樹掃瞄處理

double res = 0

; cl(sum,

0); cl(cnt,0

);

for (i = 0; i < len - 1; ++i)

printf(

"test case #%d\n

",cas++);

printf(

"total explored area: %.2lf\n\n

",res);

}return0;

}

pku 1177 picture 矩形周長並

題意:給出n個矩形,每個矩形給出左下角座標,右上角座標。然後求矩形周長的並;

思路:掃瞄線,按x軸建樹,len記錄橫向有效長度,numseg記錄叔侄方向的有效個數。然後就是掃瞄一遍過去。

#include #include 

#include

#include

#include

#include

#include

#include

#include

#include

#define cl(a,num) memset((a),(num),sizeof(a))

#define iabs(x) ((x) > 0 ? (x) : -(x))

#define min(a , b) ((a) < (b) ? (a) : (b))

#define max(a , b) ((a) > (b) ? (a) : (b))

#define ll __int64

#define inf 0x7f7f7f7f

#define mod 100000007

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define test puts("")

#define maxn 100007

#define m 10007

#define n 20007

using

namespace

std;

//freopen("din.txt","r",stdin);

struct

seg seg(

int l,int r,int h,int

mk)

bool

operator

< (const seg &tmp) const

}seg[m];

int len[n<<2],cnt[n<<2],numseg[n<<2

];int lbd[n<<2],rbd[n<<2

];void pushup(int rt,int l,int

r)

else

if (l == r) len[rt] = lbd[rt] = rbd[rt] = numseg[rt] = 0

;

else

}void update(int l,int r,int sc,int l,int r,int

rt)

int m = (l + r)>>1

;

if (l <=m) update(l,r,sc,lc);

if (m

pushup(rt,l,r);

}int

main()

sort(seg,seg +m);

int res = 0

;

int last = 0

; cl(cnt,

0); cl(numseg,0); cl(len,0

); cl(lbd,

0); cl(rbd,0

);

//掃瞄

for (i = 0; i < m; ++i)

printf(

"%d\n

",res);

return0;

}

掃瞄線 線段樹

問題描述 小明的家旁邊有條河流,但最近,周圍的三個工廠開始向這條河排放汙水,這條河的一部分被汙染了,被乙個工廠汙染的部分可以看做乙個矩形,現在小明想知道這條河被汙染的面積是多少。輸入 第一行乙個整數t,表示有多少組資料,之後每一組資料報括三行,每一行有lx,ly,rx,ry四個整數,表示被乙個工廠汙...

線段樹 掃瞄線

掃瞄線問題主要利用了線段樹。因為矩形的並集比較難算,所以我們可以用 sum 掃瞄線被截長度 所掃瞄的高度 來求和。而這樣做發現可以用線段樹來優化,具體優化方式如下 所掃瞄的高度比較好求,主要是掃瞄線被截長度需要優化。我們可以設橫邊有乙個a權值,如果該邊是矩陣的下邊則設為1,相反就設為 1,這樣如果一...

線段樹 掃瞄線

這其實是計算幾何的一部分。一般被用來解決圖形面積 周長等問題。求給定的 n 個矩形的面積並 如圖 從左到右掃 若乙個矩形的左下頂點座標為 x 1,y 1 右上頂點座標為 x 2,y 2 模板 includeusing namespace std define int long long const ...