線段樹 掃瞄線學習筆記

2022-07-22 05:06:13 字數 4669 閱讀 6985

之後有一回在luogu做了一道同樣求矩形周長的題,用了下面的模板,但是有組資料過不了,需要做如下修改:

過載運算子函式修改成:bool operator <(const p&p)const

p(){}

p(int xx,int hh,int juu)

}s[maxn

<<1

];void upfather(int k,int l,int

r)//

n kvoid update(int l,int r,int ju,int k,int l,int

r)

int mid=(l+r)>>1

;

if(l<=mid)update(l,r,ju,k<<1

,l,mid);

if(r>mid)update(l,r,ju,k<<1|1,mid+1

,r);

upfather(k,l,r);

}int search(int key,int *x,int

k)

return -1;}

struct

pp pp(

int xx,int yy)

}ans[maxn

<<2

];int solve(int tot,int up)//

tot是邊數 up是點數

return

upp;

}int

main()

sort(a,a+up);

sort(s,s+tot);

up=unique(a,a+up)-a;

int upp=solve(tot,up);

for(int i=0;i)

}2019-09-04

掃瞄線第二題 hdu1542

給定矩形資訊,求總面積。

#includeusing

namespace

std;

const

int maxn=1e2+50

;int mark[maxn<<2];//

記錄某個區間的下底邊個數

double sum[maxn<<2];//

記錄某個區間的下底邊總長度

double a[maxn<<1];//

對x進行離散化

//struct

p p(){}

p(double ll,double rr,double hh,int

juu)

}s[maxn

<<1

];void upfather(int k,int l,int

r)void update(int l,int r,int ju,int k,int l,int

r)

int mid=(l+r)>>1

;

if(l<=mid)update(l,r,ju,k<<1

,l,mid);

if(r>mid)update(l,r,ju,k<<1|1,mid+1

,r);

upfather(k,l,r);

}int search(double key,double *x,int

k)

return -1;}

double solve(int tot,int up)//

tot是邊數 up是點數

return

ans;

}int

main()

sort(a,a+tot);

sort(s,s+tot);

int up=unique(a,a+tot)-a;

printf(

"test case #%d\n

",cas);

printf(

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

",solve(tot,up));

}}

2019-09-05

第三題,poj1177

給定矩形資訊,求周長。

(好的做法應該是用線段樹的連通性維護當前掃瞄線有幾段,然後另一方向的長度直接等於2*num*h,然而我試了,不會做,只能老老實實再在另一方向掃瞄一遍。)

#include#define debug printf("!");

using

namespace

std;

typedef

long

long

ll;const

int maxn=1e4+50

;const

int inf=0x3f3f3f3f

;int mark[maxn<<2];//

記錄某個區間的下底邊個數

ll sum[maxn<<2];//

記錄某個區間的下底邊總長度

int a1[maxn<<1],a2[maxn<<1];//

對x進行離散化

//struct

ps1[maxn

<<1],s2[maxn<<1

];void upfather(int k,int l,int r,int

a)void update(int l,int r,int ju,int k,int l,int r,int

a)

int mid=(l+r)>>1

;

if(l<=mid)update(l,r,ju,k<<1

,l,mid,a);

if(r>mid)update(l,r,ju,k<<1|1,mid+1

,r,a);

upfather(k,l,r,a);

}int search(int key,int *x,int

k)

return -1;}

ll solve(

int tot,int up,p s,int a)//

tot是邊數 up是點數

return

ans;

}int

main()

; s2[tot++]=p;

a1[tot]=x2;

a2[tot]=y2;

s1[tot]=p;

s2[tot++]=p;

}sort(a1,a1+tot);sort(a2,a2+tot);

sort(s1,s1+tot);sort(s2,s2+tot);

up=unique(a1,a1+tot)-a1;

ans+=solve(tot,up,s1,a1);

memset(sum,

0,sizeof

(sum));

memset(mark,

0,sizeof

(mark));

up=unique(a2,a2+tot)-a2;

ans+=solve(tot,up,s2,a2);

printf(

"%lld\n

",ans);

}

2019-09-05 20:08:06

第四題,洛谷p382

跟第一題幾乎一樣,改點輸入輸出和乙個小細節就可以了:d。

#includeusing

namespace

std;

const

int maxn=1e5+50

;int mark[maxn<<2];//

記錄某個區間的下底邊個數

int sum[maxn<<2];//

記錄某個區間的下底邊總長度

int a[maxn<<1];//

對h進行離散化

//以縱座標作為線段(區間),對縱座標線段進行掃瞄

struct

p p(){}

p(int xx,int hh,int juu)

}s[maxn

<<1

];void upfather(int k,int l,int

r)//

n kvoid update(int l,int r,int ju,int k,int l,int

r)

int mid=(l+r)>>1

;

if(l<=mid)update(l,r,ju,k<<1

,l,mid);

if(r>mid)update(l,r,ju,k<<1|1,mid+1

,r);

upfather(k,l,r);

}int search(int key,int *x,int

k)

return -1;}

struct

pp pp(

int xx,int yy)

}ans[maxn

<<2

];int solve(int tot,int up)//

tot是邊數 up是點數

return

upp;

}int

main()

sort(a,a+up);

sort(s,s+tot);

up=unique(a,a+up)-a;

int upp=solve(tot,up);

printf(

"%d\n

",upp);

for(int i=0;i)

}

2019-09-06 15:02:29

線段樹掃瞄線 學習筆記

見注釋 參考 include include using namespace std const int n 205 struct line line n struct node tr n 2 int n,cnt double fy n xx1,xx2,yy1,yy2 void build int ...

掃瞄線 線段樹學習筆記

如果仔細觀察掃瞄器工作就會發現,掃瞄器掃瞄時是一條線從頭到尾掃一遍成像。這個演算法形象化表示也是如此。首先是掃瞄線板子題 矩形面積並。題意 在平面直角座標系中,給出若干個矩形,求所有矩形的面積並。太長不看版 對於所有矩形的端點按照縱座標排序,然後依次掃瞄矩形每加入一條線段覆蓋,線段樹查詢所有區間中覆...

線段樹 掃瞄線

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