下面兩種寫法一樣:
class
edge};
bool
cmp(edge a,edge b)
struct edge
}e[maxn*2]
;bool
cmp(edge a,edge b)
struct edge
bool
operator
<
(const edge&t)
const
}e[maxn]
;
掃瞄線說白了就是線段樹的應用,下面都是模板
線段樹詳解
面積並+離散
#include
using
namespace std;
typedef
long
long ll;
const
int maxn=
100+7;
int n,cnt,sum;
//n個點,左下和右
int x[maxn*2]
;//橫座標
struct edgee[maxn*2]
;struct nodeq[maxn*8]
;bool
cmp(edge a,edge b)
#define ls i<<1
#define rs i<<1|1
#define m(i) ((q[i].l+q[i].r)>>1)
void
build
(int i,
int l,
int r)
voidkk(
)}void
pushup
(int i)
void
update
(int i,
int l,
int r,
int xx)kk(
);int mid=
m(i);if
(r<=mid)
update
(ls,l,r,xx)
;else
if(l>mid)
update
(rs,l,r,xx)
;else
pushup
(i);kk(
);}int
main()
sort
(e,e+cnt,cmp)
;//邊按高度從小到大排序(自下而上掃瞄)
sort
(x,x+cnt)
;//離散化橫座標
int k=
unique
(x,x+cnt)
-x;// int k=1;
// for(int i=1;i// cout,0
,k-1);
for(
int i=
0;i) cout<<
"面積並為:"
<210 10 20 20
15 15 25 25
175*/
周長並
#include
using
namespace std;
typedef
long
long ll;
const
int inf=
0x3f3f3f3f
;int n,cot,sum,pre,left,right;
const
int maxn=
100+7;
struct edge
}e[maxn*2]
;bool
cmp(edge a,edge b)
//這裡一定不能去掉,比如這組資料:2 0 0 4 4 0 4 4 8--->多算中間的一條邊兩邊,先合併再捨去
#define ls i<<1
#define rs i<<1|1
#define m(i) ((l+r)>>1)
#define lson ll,rr,xx,l,mid
#define rson ll,rr,xx,mid+1,r
int len[maxn<<2]
,cover[maxn<<2]
,cnt[maxn<<2]
;//區間覆蓋的長度,覆蓋的次數,豎線的條數
bool fl[maxn*4]
,fr[maxn*4]
;//左端點是否被覆蓋,右端點是否被覆蓋
//struct nodeq[maxn*8];
void
pushup
(int i,
int l,
int r)
else
if(l==r) len[i]
=fl[i]
=fr[i]
=cnt[i]=0
;else
}void
update
(int i,
int ll,
int rr,
int xx,
int l,
int r)
int mid=
m(i);if
(ll<=mid)
update
(ls,lson);if
(rr>mid)
update
(rs,rson)
;pushup
(i,l,r);}
intmain()
sort
(e,e+cot,cmp)
;for
(int i=
0;i) cout*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
228*/
求覆蓋兩次以上的面積並
#include
#pragma gcc optimize(2)
using
namespace std;
typedef
long
long ll;
const
int inf=
0x3f3f3f3f
;const
int maxn=
2e3+7;
int n,cot,t;
double sum;
double x[maxn*2]
;int cnt[maxn*8]
;double sum1[maxn*8]
,sum2[maxn*8]
;class
edge};
bool
cmp(edge a,edge b)
edge e[maxn*2]
;#define ls i<<1
#define rs i<<1|1
#define m(i) ((l+r)>>1)
#define eps 1e-15
void
build
(int i,
int l,
int r)
void
pushup1
(int i,
int l,
int r)
void
pushup2
(int i,
int l,
int r)
void
update
(int i,
int ll,
int rr,
int xx,
int l,
int r)
int mid=
m(i);if
(ll<=mid)
update
(ls,ll,rr,xx,l,mid);if
(rr>mid)
update
(rs,ll,rr,xx,mid+
1,r)
;pushup1
(i,l,r)
;pushup2
(i,l,r);}
intmain()
sort
(e,e+cot,cmp)
;sort
(x,x+cot)
;int k=
unique
(x,x+cot)
-x;build(1
,0,k-1);
int l=
lower_bound
(x,x+k,e[0]
.x1)
-x;int r=
lower_bound
(x,x+k,e[0]
.x2)
-x;update(1
,l,r-
1,e[0]
.f,0
,cot)
;for
(int i=
1;i)printf
("%.2lf\n"
,sum);}
}/*25
1 1 4 2
1 3 3 7
2 1.5 5 4.5
3.5 1.25 7.5 4
6 3 10 7
30 0 1 1
1 0 2 1
2 0 3 1
7.63
0.00
*/
寫多了後,掃瞄線的格式基本不變,pushup函式根據題意變換 線段樹演算法 掃瞄線之面積並
一 掃瞄線演算法 基本思想 按掃瞄線順序,計算掃瞄線與多邊形的相交區間,再用要求的顏色顯示這些區間的象素,即完成填充工作。對於一條掃瞄線填充過程可以分為四個步驟 1 求交 計算掃瞄線與多邊形各邊的交點 2 排序 把所有交點按 x 座標遞增順序來排序 3 配對 確定掃瞄線與多邊形的相交區間,第乙個與第...
codevs 3044 矩形面積求並 (掃瞄線)
之前一直偷懶離散化 暴力做著題 今天搞一下掃瞄線 自己按照線段樹的一般寫法寫的有些問題 因為不用於以前的區間sum so題解搬運者23333 orz 去掉了打標記的過程 同時更新區間的時候先判斷是不是已經需要賦值 還有一些細節的處理 線段樹是離散化之後的x軸建的 每個線段的權值轉移到點上 每個點代表...
線段樹 掃瞄法解決矩形的面積並 周長並問題
矩形的面積並問題 平面上有n個矩形,各邊均平行於座標軸,求它們覆蓋的總面積 重複覆蓋的只計一次 矩形的周長並問題 平面上有n個矩形,各邊均平行於座標軸,求它們覆蓋形成的多邊形的周長。演算法 面積並 先將所有矩形的上邊界和下邊界作為水平線段記錄下來,並對所有矩形的左右邊界對應的橫座標離散化,設離散化後...