給一些矩形的頂點,求它們重疊了兩次及以上的部分的面積。
這個題需要在掃瞄線求矩形面積的基礎上修改一些,不是簡單的求出所有矩形的面積,再減去實際的面積。因為由的部分是覆蓋了三次及以上的直接減去是錯誤的。
需要額外增加乙個陣列用來儲存覆蓋兩次及以上的面積的長,維護這個陣列的話只需要每次更新的時候計算一下。
其他的地方和簡單的掃瞄線求矩形面積並沒有什麼區別。
#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的...