給出n個矩形的左下角和右上角的座標,求矩形面積的並。
矩形面積並指的是被矩形覆蓋到的面積和,重疊部分僅算一次。
多組輸入,每組首先乙個整數 n,代表矩形的數量;
接下來每行四個整數 x1,x2,y1,y2,表示左上角座標(x1,y1)與右下角(x2,y2)
每行乙個整數,表示矩形的面積並。
input10 0 10 10
20 0 10 10
5 5 6 6
0output
100100
1 ≤\leq
≤ n ≤
\leq
≤ 1e5
1 ≤
\leq
≤ x1 <
<
<
x2 ≤
\leq
≤ 1e5
1 ≤
\leq
≤ y1 <
<
<
y2 ≤
\leq
≤ 1e5
time limit:2000 ms
memory limit: 256 mb
很容易發現,這個題目就是把一維的區間覆蓋問題變成了二維的矩形覆蓋問題。還是看圖理解吧。。。一維的區間覆蓋問題就是裸的線段樹問題,所以剛拿到這題的我就以為是乙個裸的二維線段樹問題。然而,看到資料範圍,我就傻了,二維線段樹的空間複雜度是v( n
2n^2
n2), 所以可以直接否決二維線段樹了。
但是這個資料範圍告訴我們基本可以確定是線段樹了,但我們只能對其中乙個維度進行線段樹維護。矩形面積不是等於長*寬嗎,我們用線段樹維護了長度,再乘以乙個高就是面積了。
我們可以根據每條橫邊的高度,將圖形分塊
我們可以根據矩形上下邊界的高度將圖形分為若干塊,用每塊的高度乘上這塊的區間覆蓋長度就是這一塊的面積。這個區間覆蓋長度就是一維的線段樹問題。從上往下計算時,上邊界加,下邊界減。
1.讀入每個矩形的兩個角座標
2.將矩形上下邊界的左右端點位置、高度、型別(上邊界or下邊界)資訊存入
3.對這2n條線段按高度排序
4.掃瞄每條線段,對線段樹進行修改,修改後查詢覆蓋區間長度
5.統計答案 ans+=len*high;
每次修改的時間複雜度為o(log
(r−l
)\ log(r-l)
log(r−
l))每次查詢的時間複雜度為o(log
(r−l
)\ log(r-l)
log(r−
l))r為右邊界,l為左邊界,r-l是 105
10^5
105級別
總的時間複雜度為o(nlog
nlogn
logn
)
#include
#include
#include
#include
#include
#include
#define for(i,a,b) for(register int i=(a);i<=(b);++i)
#define ls node<<1
#define rs node<<1|1
#define ll long long
using
namespace std;
const
int maxx=
1e5+10;
intread()
while
(isdigit
(x))
return fg?
-u:u;
}struct segment
}s[maxx<<1]
;int tr[maxx<<2]
,lazy[maxx<<2]
;int n,cnt,l,r;
void
tag(
int node,
int l,
int r,
bool add)
else
}void
push_up
(int node)
void
push_down
(int node,
int l,
int r,
int mid)
void
update
(int node,
int l,
int r,
int x,
int y,
bool add)
if(l>=r)
return
;int mid=
(l+r)
>>1;
push_down
(node,l,r,mid);if
(mid>=y)
update
(ls,l,mid,x,y,add)
;else
if(x>mid)
update
(rs,mid+
1,r,x,y,add)
;else
push_up
(node);}
ll query
(int node,
int l,
int r)
intmain()
sort
(s,s+cnt)
;update(1
,l,r,s[0]
.l,s[0]
.r,s[0]
.up)
; len=
query(1
,l,r)
; ans=0;
for(i,
1,cnt-1)
printf
("%lld\n"
,ans);}
return0;
}
線段樹矩形面積並,面積交,周長並
include include include include using namespace std const int maxn 2000 10 define lson l,mid,rt 1 define rson mid 1,r,rt 1 1 struct rec rec maxn 2 str...
線段樹常用案例2 矩形面積並
來看一道題目 atlantis 這道題的題意是給定若干個平行於座標軸的矩形,求出這若干個矩形的面積之和,如果有重合的部分,只算一次。首先考慮暴力的演算法,即遍歷每個矩形,用乙個vis陣列記錄每個點的訪問狀態,最後可以統計出總的面積,這種方法在資料小且邊長為整數的時候適用。這類問題應該引入掃瞄線來做,...
矩形周長並,矩形面積並,矩形面積交
目錄 矩形周長並 矩形面積並 矩形面積交 includeusing namespace std const int maxn 50004 2 struct nodesegtree maxn 2 struct lineline maxn bool cmp line a,line b void cal ...