線段樹掃瞄線練習

2022-05-09 14:39:11 字數 3520 閱讀 4892

概述:

掃瞄線是解決座標系內矩形範圍內統計問題的好方法(個人理解不一定對)

就維護乙個區間,就像一根掃瞄線,沿這個區間垂直的方向遍歷乙個矩形區域(線動成面^_^)

遇到要求的答案更新至線段樹中,豈不是很優秀。

1.求矩形面積:

hdu1542

大意:給幾個矩形(有重疊部分),求整體面積。

解題思路:

就是很樸素的掃瞄線想法,將整個圖形切割成若干個能夠用底乘高求出的形狀。

將輸入按照y座標排序,用線段樹維護底長,每進入一條撤銷或覆蓋操作更新總邊長,用總邊長乘以高度差更新答案即可^_^

注意:長度為實數,做一下離散化就好了。

1 #include2 #include3 #include4 #include5

#define lll spc<<1

6#define rrr spc<<1|1

7struct

pct21 }pc[1000000

];22 std::mapm;

23int

n;24

int num[1000000

];25

double len[1000000

];26

double rx[1000000

];27

bool

cmp(pct x,pct y)

2831

bool dcp(double x,double

y)32

35namespace

sgt46

void sbuild(int l,int r,int

spc)

4757

void supdate(int ll,int rr,int l,int r,int spc,int

cmd)

5867

int mid=(l+r)>>1;68

supdate(ll,rr,l,mid,lll,cmd);

69 supdate(ll,rr,mid+1

,r,rrr,cmd);

70spushup(spc,l,r);71}

72}73int

main()

7495 std::sort(rx+1,rx+rnt+1

,dcp);

96for(int i=1;i<=rnt;i++)

97102

for(int i=1;i<=cnt;i++)

103107 std::sort(pc+1,pc+cnt+1

,cmp);

108 sgt::sbuild(1,dnt,1

);109

double btn=0.00

;110

double lst=0.00

;111

for(int i=1;i<=cnt;i++)

112118 t++;

119 printf("

test case #%d\n

",t);

120 printf("

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

",ans);

121}

122return0;

123 }

2.求矩形周長:

hdu1828

大意:給幾個矩形(有重疊部分),求整體周長。

解題思路:

首先最樸素的掃瞄線演算法就是,先掃一遍橫線,再掃一遍豎線,最後統計答案

也就是說,我們只要統計橫線或豎線就好了。

具體怎麼做呢,將輸入存為兩條平行於掃瞄線的區間,第一遍叫加入,第二邊叫取消,區間查詢總長度-上次長度更新答案即可。

掃兩遍嘛,比較麻煩,其實掃一遍是加入區間多少個不連續就好了這個就是豎邊的數量再乘以豎邊長度即可^_^

注意一下邊的重合先處理頂邊就好了。

**(怕re開大了線段樹的區間就有點小慢):

1 #include2 #include3 #include4

#define lll spc<<1

5#define rrr spc<<1|1

6 typedef long

long

lnt;

7struct

trnt

17 }tr[1000000

];18

struct

pctpc[1000000

];23

intn;

24int

cnt;

25namespace

sgt36

void

sdestory()

3740

void spushup(int spc,int l,int

r)41

49if(l==r)

5054 tr[spc].len=tr[lll].len+tr[rrr].len;

55 tr[spc].nar=tr[lll].nar+tr[rrr].nar;

56 tr[spc].cl=tr[lll].cl;

57 tr[spc].cr=tr[rrr].cr;

58if(tr[lll].cr&&tr[rrr].cl)

59 tr[spc].nar--;

60return;61

}62void supdate(int l,int r,int ll,int rr,int spc,int

cmd)

6372

int mid=(l+r)>>1;73

supdate(l,mid,ll,rr,lll,cmd);

74 supdate(mid+1

,r,ll,rr,rrr,cmd);

75spushup(spc,l,r);76}

77}78bool

cmp(pct x,pct y)

7984

intmain()85;

101 cnt++;

102 pc[cnt]=(pct);

103}

104 std::sort(pc+1,pc+cnt+1

,cmp);

105int lst=tr[1

].len;

106for(int i=1;i<=cnt;i++)

107112 printf("

%lld\n

",ans);

113}

114return0;

115 }

3.平面內離散化點的統計:

這個就是將矩形區域內的答案存起來之後每進乙個點查詢整個矩形區域更新答案即可。

線段樹 掃瞄線

pku 1151 hdu1542 atlantis 矩形面積並 題意 給出n個矩形,每個矩形給出左下角座標,右上角座標。然後求矩形並的總面積 思路 浮點數先要離散化 然後把矩形分成兩條邊,上邊和下邊,對橫軸建樹,然後從下到上掃瞄上去,用cnt表示該區間下邊比上邊多幾個,sum代表該區間內被覆蓋的線段...

掃瞄線 線段樹

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

線段樹 掃瞄線

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