HDU1255 求覆蓋兩次及以上的矩形面積 掃瞄線

2021-10-07 22:16:36 字數 1907 閱讀 2085

兩次的覆蓋不僅僅單獨的改變cnt的判斷條件

而是要進行討論,儘管現在只有1層標記或者沒有標記 仍然可能對當前做出貢獻

也就是:

分情況討論

1.cnt>1 : 說明該區間被覆蓋兩次或以上,那麼長度就可以直接計算,就是該區間的長度,剩下的情況就是cnt=1或cnt=0

2.先看葉子節點,因為是葉子沒有孩子了,所以被覆蓋兩次貨以上的長度就是0(無論cnt=1或cnt=0都是0,因為是葉子。。。)

3.不是葉子節點 ,且cnt=1.注意這裡,cnt=1確切的意義是什麼,應該是,可以確定,這個區間被完全覆蓋了1次,而有沒有被完全覆蓋兩次或以上則不知道無法確定,那麼怎麼怎麼辦了,只要加上t[lch].s + t[rch].s 即,看看左右孩子區間被覆蓋了一次或以上的長度,那麼疊加在雙親上就是雙親被覆蓋兩次或以上的長度

3.不是葉子節點,且cnt=0,確切的意義應該是不完全不知道被覆蓋的情況(不知道有沒有被覆蓋,被覆蓋了幾次,長度是多少都不知道),這種情況,只能由其左右孩子的資訊所得

t[lch].ss + t[rch].ss , 即直接將左右孩子給覆蓋了兩次或以上的長度加起來,這樣才能做到不重不漏

**

#include

using

namespace std;

typedef

long

long ll;

const

int maxn =

1e5+7;

struct node

line[maxn]

;double lsh[maxn]

;double tree[maxn][3

];int ct[maxn]

;int n;

bool

cmp(node a,node b)

//如果單純的 只考慮 ct>1的情況 會漏掉很多面積 要分類討論才不會少

// 通過分類討論的思想也就可以類似的求 三次 四次的面積 都是可以推得的

void

pushup

(int rt,

int l,

int r)

void

build

(int rt,

int l,

int r)

void

update

(int rt,

int l,

int r,

int ul,

int ur,

int x)

int mid =

(l+r)

>>1;

if(ul <= mid)

update

(rt<<

1,l,mid,ul,ur,x);if

(ur > mid)

update

(rt<<1|

1,mid+

1,r,ul,ur,x)

;pushup

(rt,l,r);}

intmain()

sort

(lsh+

1,lsh+cnt+1)

;sort

(line+

1,line+cnt+

1,cmp)

;int num =

unique

(lsh+

1,lsh+

1+cnt)

-lsh-1;

//printf("%d\n",num);

build(1

,1,num)

;double ans =0;

for(

int i =

1;i <= cnt;i ++

)printf

("%.2f\n"

,ans);}

return0;

}

覆蓋的面積 HDU 1255 (求面積的交)

題目 給定平面上若干矩形,求出被這些矩形覆蓋過至少兩次的區域的面積.分析 在求面積並的基礎上增加了乙個成員len2,記錄被覆蓋至少兩次的長度,num標記表示這一部分至少被全覆蓋了幾次 num 1不一定代表這一段覆蓋了只覆蓋一次,還要看子節點 同時考慮離散化。1 include 2 using nam...

HDU 1255 掃瞄線求二次覆蓋的面積 線段樹

hdu 1255 add 1說明覆蓋 2次可以直接計算覆蓋長度q i len2 x q i r 1 x q i l 如果是葉節點就q i len2 0add 1說明當前節點區間被覆蓋了一次,想要求得覆蓋 2次的區間,此時還要考慮子區間被覆蓋的情況 加上子區間被覆蓋 1次的區間長度,累加起來就被覆蓋 ...

覆蓋的面積 HDU 1255 掃瞄線 二次覆蓋

includeusing namespace std define ll long long const int maxn 1010 int n double x maxn 1 struct edge edge double a,double b,double c,int d l a r b h c...