pku 1151 && hdu1542 atlantis 矩形面積並
題意:給出n個矩形,每個矩形給出左下角座標,右上角座標。然後求矩形並的總面積;
思路:浮點數先要離散化;然後把矩形分成兩條邊,上邊和下邊,對橫軸建樹,然後從下到上掃瞄上去,用cnt表示該區間下邊比上邊多幾個,sum代表該區間內被覆蓋的線段的長度總和
這裡線段樹的乙個結點並非是線段的乙個端點,而是該端點和下乙個端點間的線段,所以題目中r+1,r-1的地方可以自己好好的琢磨一下;
這裡點到線段的轉化不好理解:
我們的線段樹的葉子節點表示的是線段,座椅如果我們求1到4的線段長度是實際上是求的1,2,3好線段,所以r要-1,而當我們真正求長度是是x[i + 1] - x[i]才是i線段的長度。
#include #includepku 1177 picture 矩形周長並#include
#include
#include
#include
#include
#include
#include
#include
#define cl(a,num) memset((a),(num),sizeof(a))
#define iabs(x) ((x) > 0 ? (x) : -(x))
#define min(a , b) ((a) < (b) ? (a) : (b))
#define max(a , b) ((a) > (b) ? (a) : (b))
#define ll __int64
#define inf 0x7f7f7f7f
#define mod 100000007
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define test puts("")
#define maxn 100007
#define m 100007
#define n 227
using
namespace
std;
//freopen("din.txt","r",stdin);
struct
seg seg(
double l,double r,double h,int
mk)
bool
operator
< (const seg &tmp) const
}seg[n];
int cnt[n<<2
];double sum[n<<2
],x[n];
void pushup(int rt,int l,int
r)void update(int l,int r,int sc,int l,int r,int
rt)
int m = (l + r)>>1
;
if (l <=m) update(l,r,sc,lc);
if (m
pushup(rt,l,r);}//
離散化後二分查詢
int bsearch(double val,int
n)
returnl;}
intmain()
//離散化
sort(x,x +len);
sort(seg,seg +len);
int k = 1
;
for (i = 1; i < len; ++i)
//線段樹掃瞄處理
double res = 0
; cl(sum,
0); cl(cnt,0
);
for (i = 0; i < len - 1; ++i)
printf(
"test case #%d\n
",cas++);
printf(
"total explored area: %.2lf\n\n
",res);
}return0;
}
題意:給出n個矩形,每個矩形給出左下角座標,右上角座標。然後求矩形周長的並;
思路:掃瞄線,按x軸建樹,len記錄橫向有效長度,numseg記錄叔侄方向的有效個數。然後就是掃瞄一遍過去。
#include #include#include
#include
#include
#include
#include
#include
#include
#include
#define cl(a,num) memset((a),(num),sizeof(a))
#define iabs(x) ((x) > 0 ? (x) : -(x))
#define min(a , b) ((a) < (b) ? (a) : (b))
#define max(a , b) ((a) > (b) ? (a) : (b))
#define ll __int64
#define inf 0x7f7f7f7f
#define mod 100000007
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define test puts("")
#define maxn 100007
#define m 10007
#define n 20007
using
namespace
std;
//freopen("din.txt","r",stdin);
struct
seg seg(
int l,int r,int h,int
mk)
bool
operator
< (const seg &tmp) const
}seg[m];
int len[n<<2],cnt[n<<2],numseg[n<<2
];int lbd[n<<2],rbd[n<<2
];void pushup(int rt,int l,int
r)
else
if (l == r) len[rt] = lbd[rt] = rbd[rt] = numseg[rt] = 0
;
else
}void update(int l,int r,int sc,int l,int r,int
rt)
int m = (l + r)>>1
;
if (l <=m) update(l,r,sc,lc);
if (m
pushup(rt,l,r);
}int
main()
sort(seg,seg +m);
int res = 0
;
int last = 0
; cl(cnt,
0); cl(numseg,0); cl(len,0
); cl(lbd,
0); cl(rbd,0
);
//掃瞄
for (i = 0; i < m; ++i)
printf(
"%d\n
",res);
return0;
}
掃瞄線 線段樹
問題描述 小明的家旁邊有條河流,但最近,周圍的三個工廠開始向這條河排放汙水,這條河的一部分被汙染了,被乙個工廠汙染的部分可以看做乙個矩形,現在小明想知道這條河被汙染的面積是多少。輸入 第一行乙個整數t,表示有多少組資料,之後每一組資料報括三行,每一行有lx,ly,rx,ry四個整數,表示被乙個工廠汙...
線段樹 掃瞄線
掃瞄線問題主要利用了線段樹。因為矩形的並集比較難算,所以我們可以用 sum 掃瞄線被截長度 所掃瞄的高度 來求和。而這樣做發現可以用線段樹來優化,具體優化方式如下 所掃瞄的高度比較好求,主要是掃瞄線被截長度需要優化。我們可以設橫邊有乙個a權值,如果該邊是矩陣的下邊則設為1,相反就設為 1,這樣如果一...
線段樹 掃瞄線
這其實是計算幾何的一部分。一般被用來解決圖形面積 周長等問題。求給定的 n 個矩形的面積並 如圖 從左到右掃 若乙個矩形的左下頂點座標為 x 1,y 1 右上頂點座標為 x 2,y 2 模板 includeusing namespace std define int long long const ...