掃瞄線,矩形覆蓋兩次及以上的面積hdu1255

2021-09-28 21:21:01 字數 1367 閱讀 3129

給一些矩形的頂點,求它們重疊了兩次及以上的部分的面積。

這個題需要在掃瞄線求矩形面積的基礎上修改一些,不是簡單的求出所有矩形的面積,再減去實際的面積。因為由的部分是覆蓋了三次及以上的直接減去是錯誤的。

需要額外增加乙個陣列用來儲存覆蓋兩次及以上的面積的長,維護這個陣列的話只需要每次更新的時候計算一下。

其他的地方和簡單的掃瞄線求矩形面積並沒有什麼區別。

#pragma warning(disable:4996)

#include#include#include#include#include#includeusing namespace std;

typedef long long ll;

const int maxn = 20005;

struct node

};node line[maxn];

double sum[maxn], x[maxn], ss[maxn];

//ss代表被覆蓋兩次及以上的長度,sum代表覆蓋一次及以上的長度

ll mark[maxn];

void pushup(ll l, ll r, ll k)

else if (l == r)sum[k] = 0;

else sum[k] = sum[2 * k] + sum[2 * k + 1];

//大於1直接計算出長度

if (mark[k] > 1)

else if (l == r)ss[k] = 0;

//等於1的時候,相當於原來被覆蓋一次的部分被覆蓋了兩次

else if (mark[k] == 1)ss[k] = sum[2 * k] + sum[2 * k + 1];

else ss[k] = ss[2 * k] + ss[2 * k + 1];

}void update(ll k, ll l, ll r, ll val, ll l, ll r)

ll mid = (l + r) / 2;

if (l <= mid)update(2 * k, l, r, val, l, mid);

if (r > mid)update(2 * k + 1, l, r, val, mid + 1, r);

pushup(l, r, k);

}int main()

//排序去重

sort(line + 1, line + 1 + k);

sort(x + 1, x + 1 + k1);

k1 = unique(x + 1, x + 1 + k1) - x - 1;

ll l, r;

for (i = 1; i printf("%.2lf\n", ans);

} return 0;

}

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

兩次的覆蓋不僅僅單獨的改變cnt的判斷條件 而是要進行討論,儘管現在只有1層標記或者沒有標記 仍然可能對當前做出貢獻 也就是 分情況討論 1.cnt 1 說明該區間被覆蓋兩次或以上,那麼長度就可以直接計算,就是該區間的長度,剩下的情況就是cnt 1或cnt 0 2.先看葉子節點,因為是葉子沒有孩子了...

覆蓋的面積 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...

hdu 1255 覆蓋的面積 掃瞄線

一道挺簡單的題,讓我折騰了許久。主要卡在了更新節點後維護父親節點上。後來思路明確了就很容易了。節點資訊 l,r 區間端點 cnt 區間被覆蓋的次數,cnt 0說明沒有被完全覆蓋。len1 區間被覆蓋的長度 len2 區間至少被兩條線段覆蓋的長度。只要找到父親節點與子節點在len1,len2,cnt的...