掃瞄線小整理 HDU1542 HDU1255

2021-09-24 20:20:25 字數 4216 閱讀 9622

以前一直沒仔細學一波掃瞄線,最近終於補了一下。

大致的思想:將座標的一維離散化,然後建立線段樹,維護當前被覆蓋的線段長度,然後將另一維排序,按順序插入線段樹。對於乙個矩形的上底邊和下底邊,(如果從下往上掃瞄)則對下底邊作+1標記,上底邊作-1標記。用乙個結構體儲存一條邊的資訊,包括l:線段左端點,r:線段右端點,h:線段的高度,d:線段的上下底邊標記。線段樹的乙個細節是,每個節點代表的是第幾段線段,而不是某個線段的端點,所以線段[l,r]代表的是第l段線段到第r段線段,

其真實長度=v[r+1]-v[l];(其中v陣列是離散化陣列) 每次兩線段之間的面積就是兩線段高度差*x軸方向覆蓋的線段長度。

#include

using namespace std;

#define maxn 100005

#define ll long long int

#define inf 0x3f3f3f3f

int n,m;

struct node};

node a[maxn<<1]

;vector<

double

>v;

int tot;

int cnt[maxn<<2]

;double sum[maxn<<2]

;void

pushup

(int x,

int l,

int r)

void

update

(int x,

int l,

int r,

int lp,

int rp,

int s)

int mid=

(l+r)

>>1;

if(lp<=mid)

update

(x<<

1,l,mid,lp,rp,s);if

(mid+

1<=rp)

update

(x<<1|

1,mid+

1,r,lp,rp,s)

;pushup

(x,l,r);}

intmain()

; a[

++tot]=;

v.push_back

(x1)

; v.

push_back

(x2);}

sort

(v.begin()

,v.end()

);sort

(a+1

,a+tot+1)

;int len=

unique

(v.begin()

,v.end()

)-v.

begin()

;double ans=0;

for(

int i=

1;i<=tot;i++

)printf

("%lf\n"

,ans)

;return0;

}

模板題,給定n個矩形,求覆蓋的總面積。注意格式,每次輸出之後要跟乙個換行。

#include

.h>

using namespace std;

#define maxn 205

#define ll long

long

int#define inf 0x3f3f3f3f

int n;

struct node

}a[maxn<<1]

;int tot;

vector<

double

>

v;int cnt[maxn<<2]

;double sum[maxn<<2]

;void

pushup

(int x,

int l,

int r)

void

update

(int x,

int l,

int r,

int lp,

int rp,

int s)

int mid=

(l+r)

>>1;

if(lp<=mid)

update

(x<<

1,l,mid,lp,rp,s);if

(mid+

1<=rp)

update

(x<<1|

1,mid+

1,r,lp,rp,s)

;pushup

(x,l,r);}

intmain()

; a[

++tot]=;

v.push_back

(x1)

; v.

push_back

(x2);}

sort

(v.begin()

,v.end()

);sort

(a+1

,a+tot+1)

;int len=

unique

(v.begin()

,v.end()

)-v.

begin()

;double ans=0;

for(

int i=

1;i<=tot;i++

)printf

("test case #%d\n"

,++kase)

;printf

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

,ans);}

return0;

}

題意如圖:

然後對於sum[x][0]的更新也要仔細討論。詳細見**。

///覆蓋兩次以上的面積

#include

using namespace std;

#define maxn 2005

#define ll long long int

#define inf 0x3f3f3f3f

int n,t;

struct node

}a[maxn<<1]

;int tot;

vector<

double

>v;

int cnt[maxn<<2]

;double sum[maxn<<2]

[2];

void

pushup

(int x,

int l,

int r)

else

else}}

}void

update

(int x,

int l,

int r,

int lp,

int rp,

int s)

int mid=

(l+r)

>>1;

if(lp<=mid)

update

(x<<

1,l,mid,lp,rp,s);if

(mid+

1<=rp)

update

(x<<1|

1,mid+

1,r,lp,rp,s)

;pushup

(x,l,r);}

intmain()

; a[

++tot]=;

v.push_back

(x1)

; v.

push_back

(x2);}

sort

(v.begin()

,v.end()

);sort

(a+1

,a+tot+1)

;int len=

unique

(v.begin()

,v.end()

)-v.

begin()

;double ans=0;

for(

int i=

1;i<=tot;i++

)printf

("%.2lf\n"

,ans);}

return0;

}

hdu1542(線段樹 掃瞄線)

裸的掃瞄線,學習掃瞄線的題目。具體掃瞄線的原理我不講了,我是看大神們的部落格懂得,就算寫也沒大神屌。下面我給出我的 裡面的注釋是我認為比較重要的地方 include include include includeusing namespace std const int max 210 int n ...

hdu 1542 掃瞄線 線段樹

題目大意 求矩形面積的並 思路 按y軸排序,然後將x投影到線段樹上做乙個線段覆蓋問題即可 注意 為了避免重複,線段座標右端點是開區間,更新時需要加上1 include include include include include define fo i,a,b for int i a i b i ...

hdu1542(線段樹 掃瞄線)

題目連線 又看到了幾個月前做的題,感覺那時候就是個sb 也怪自己剛開始沒搞清楚線段樹,瞎摸索 用連續線段樹很好理解這個題,之前的 稍微改了一下就好理解多了 1 include2 include3 include4 define lson l,m,rt 1 5 define rson m,r,rt 1...