線段樹掃瞄線求矩形周長詳解

2021-08-19 06:59:40 字數 3101 閱讀 1252

oi比賽中掃瞄線是一種很常用的演算法,矩形周長是乙個模板題。

題目鏈結

比如,對於下面的三個矩形:

想象有一條掃瞄線,從下往上掃瞄完整個圖案,每遇到一條上邊或者下邊就停下來:

然後每次停下後對區間進行處理,用乙個ans代表當前周長,最後ans就是答案。

首先,要先把矩形拆成上邊和下邊,用1和-1分別代表上邊和下邊。然後按高度排序,這樣陣列從前往後處理就相當於掃瞄線從下往上掃瞄。如果是下邊,就在對應區間上加1,如果是上邊,就在對應區間上減1。

在整個區間上建一棵線段樹:

#define lson o<<1

#define rson o<<1|1

#define mid (l+r)/2

struct tree

//如果不懂也沒有關係,接著往下看

那麼pushup要怎麼寫呢?

void pushup(int o,int l,int r)

else if(l==r)//這是乙個葉節點

else//一般情況

}

有了pushup,add函式就好寫了:

void add(int o,int l,int r,int from,int to,int value)

//此區間為[l,r],待修改區間為[from,to],新增值為value。

先遞迴處理:

再pushup:

(懶得分開寫了)

遞迴處理,pushup:

至此,總算說完了線段樹的修改。

突然想起乙個很嚴肅的事情來:答案怎麼統計?

對於橫邊,相鄰兩次修改的區間覆蓋長度差(就是tree[root].len的差)加起來就是答案(不理解的自己想辦法理解,反正我不理解);

怎麼記錄呢?

對了,就是tree[root].num*2*(h2-h1)(num的作用在這裡)

好了,下面是完整**:

#include#include#include#define lson o<<1

#define rson o<<1|1

#define mid (l+r)/2

using namespace std;

struct edge

e[10005];

struct tree

tree[100005];

int n,mx=-2147483647,mn=2147483647,edgenum,ans,last;

void add_edge(int l,int r,int h,int f)

bool cmp(edge a,edge b)

void pushup(int o,int l,int r)

else if(l==r)

else }

void add(int o,int l,int r,int from,int to,int value)

if(from<=mid)add(lson,l,mid,from,to,value);

if(to>mid)add(rson,mid+1,r,from,to,value);

pushup(o,l,r);

}int main()

if(mn<=0)

mx-=mn;

} sort(e+1,e+edgenum+1,cmp);

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

ans+=abs(tree[1].len-last);

last=tree[1].len;

ans+=tree[1].num*2*(e[i+1].height-e[i].height);

} printf("%d\n",ans);

return 0;

}

最後給兩個卡死我的樣例:

樣例輸入1:

7

-15 0 5 10

-5 8 20 25

15 -4 24 14

0 -6 16 4

2 15 10 22

30 10 36 20

34 0 40 16

樣例輸出1:

228
樣例輸入2:

2

0 0 4 4

0 4 4 8

樣例輸出2:

24

hdu 1828線段樹掃瞄線求周長並

include include include include include include include include include include include include include include include define iinf 2000000000 define ...

線段樹求矩形面積並 掃瞄線 離散化

顧名思義,掃瞄法就是用一根想象中的線掃過所有矩形,在寫 的過程中,這根線很重要。方向的話,可以左右掃,也可以上下掃。方法是一樣的,這裡我用的是由下向上的掃瞄法。如上圖所示,座標系內有兩個矩形。位置分別由左下角和右上角頂點的座標來給出。上下掃瞄法是對x軸建立線段樹,矩形與y平行的兩條邊是沒有用的,在這...

線段樹求矩形面積並 掃瞄線 離散化

顧名思義,掃瞄法就是用一根想象中的線掃過所有矩形,在寫 的過程中,這根線很重要。方向的話,可以左右掃,也可以上下掃。方法是一樣的,這裡我用的是由下向上的掃瞄法。如上圖所示,座標系內有兩個矩形。位置分別由左下角和右上角頂點的座標來給出。上下掃瞄法是對x軸建立線段樹,矩形與y平行的兩條邊是沒有用的,在這...