先儲存個大佬的模板然後慢慢研究。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 99999999
using
namespace std;
const
int max=
200+10;
int mark[max<<2]
;//記錄某個區間的下底邊個數
double sum[max<<2]
;//記錄某個區間的下底邊總長度
double hash[max]
;//對x進行離散化,否則x為浮點數且很大無法進行線段樹
//以橫座標作為線段(區間),對橫座標線段進行掃瞄
//掃瞄的作用是每次更新下底邊總長度和下底邊個數,增加新面積
struct seg
seg(
double x1,
double x2,
double h,
int c):l
(x1),r
(x2),h
(h),
d(c)
bool
operator
<
(const seg &a)
const
}s[max]
;void
upfather
(int n,
int left,
int right)
void
update
(int l,
int r,
int d,
int n,
int left,
int right)
int mid=left+right>>1;
if(l<=mid)
update
(l,r,d,n<<
1,left,mid);if
(r>mid)
update
(l,r,d,n<<1|
1,mid+
1,right)
;upfather
(n,left,right);}
intsearch
(double key,
double
* x,
int n)
return-1
;}intmain()
sort
(hash,hash+k)
;sort
(s,s+k)
;int m=1;
for(
int i=
1;i++i)
//去重複端點
if(hash[i]
!= hash[i-1]
)hash[m++
]=hash[i]
;double ans=0;
//memset(mark,0,sizeof mark);
//memset(sum,0,sizeof sum);如果下面是ifor
(int i=
0;i++i)
printf
("test case #%d\ntotal explored area: %.2lf\n\n"
,++num,ans);}
return0;
}/*這裡注意下掃瞄線段時r-1:int r=search(s[i].l,hash,m)-1;
計算底邊長時r+1:if(mark[n])sum[n]=hash[right+1]-hash[left];
解釋:假設現在有乙個線段左端點是l=0,右端點是r=m-1
則我們去更新的時候,會算到sum[1]=hash[mid]-hash[left]+hash[right]-hash[mid+1]
這樣的到的底邊長sum是錯誤的,why?因為少算了mid~mid+1的距離,由於我們這利用了
離散化且區間表示線段,所以mid~mid+1之間是有長度的,比如hash[3]=1.2,hash[4]=5.6,mid=3
所以這裡用r-1,r+1就很好理解了
*/
O 覆蓋的面積 (線段樹 掃瞄線)
給定平面上若干矩形,求出被這些矩形覆蓋過至少兩次的區域的面積.input 輸入資料的第一行是乙個正整數t 1 t 100 代表測試資料的數量.每個測試資料的第一行是乙個正整數n 1 n 1000 代表矩形的數量,然後是n行資料,每一行包含四個浮點數,代表平面上的乙個矩形的左上角座標和右下角座標,矩形...
HDU 1255 覆蓋的面積 線段樹 掃瞄線
還是先離散化座標,然後用線段樹掃瞄線 其中sum代表被覆蓋過一次的長度,sum2代表被覆蓋過2次及以上的長度。然後注意pushup操作比較麻煩。id sdj22251 prog subset lang c include include include include include include...
hdu 1255 覆蓋的面積 線段樹 掃瞄線
一直想搞線段樹的掃瞄線,這道題算是入門了吧。這題需要用到 離散化,因為座標是浮點數。還有就是線段樹中的掃瞄線的知識,另外,這題需要求重複的面積和,所以在運用線段樹的時候需要更新到葉子節點。每乙個葉子節點儲存的是離散化後長度為1的線段。跟區間更新啥的還是挺像的,就是那些乙個葉子節點表示乙個點,這個是表...