hdu 1255 覆蓋的面積 掃瞄線

2021-06-23 06:05:16 字數 1836 閱讀 1302

一道挺簡單的題,讓我折騰了許久。主要卡在了更新節點後維護父親節點上。後來思路明確了就很容易了。

節點資訊:

l,r:區間端點

cnt:區間被覆蓋的次數,cnt = 0說明沒有被完全覆蓋。

len1:區間被覆蓋的長度

len2:區間至少被兩條線段覆蓋的長度。

只要找到父親節點與子節點在len1,len2,cnt的關係就簡單了。

#include #include #include #include #include #include #include #include #include #include #include #include #include #define ll long long

#define _ll __int64

#define eps 1e-12

#define pi acos(-1.0)

using namespace std;

const int inf = 0x3f3f3f3f;

const int maxn = 1010;

double x[maxn*2];

struct line

}line[maxn*2];

struct node

tree[maxn*8];

int binsearch(int l, int r, double key)

return -1;

}void build(int v, int l, int r)

/*重點。

若該節點的cnt >= 2,說明被至少兩條線段覆蓋,那麼len1=len2=區間長度。

若該節點的cnt == 1,說明該區間被一條線段覆蓋,len1=區間長度,只要左右節點的len1有值,

那麼那些長度一定是至少被覆蓋兩次的,因此len2為左右節點的len1之和。

若該節點的cnt = 0,說明沒被完全覆蓋,直接用其左右節點更新。

還要注意特判葉子節點。

*/void maintain(int v)

if(tree[v].cnt == 1)

if(tree[v].cnt == 0)

return; }}

void update(int v, int l, int r, int tag)

int mid = (tree[v].l + tree[v].r) >> 1;

if(r <= mid)

update(v*2,l,r,tag);

else if(l > mid)

update(v*2+1,l,r,tag);

else

maintain(v);

return;

}int main()

; x[cnt] = x1;

line[++cnt] = (struct line);

x[cnt] = x2;

} sort(x+1,x+1+cnt);

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

k = 1;

for(int i = 2; i <= cnt; i++)

build(1,1,k);

double ans = 0;

for(int i = 1; i < cnt; i++)

printf("%.2lf\n",ans);

} return 0;

}

覆蓋的面積 HDU 1255(掃瞄線求面積交)

題意 就是掃瞄線求面積交 解析 參考求面積並。就是把down的判斷條件改了一下。由w 0 改為 w 1 同時要討論一下 1 時 的情況,所以就要用到乙個臨時的sum。具體看 把 include include include include include include include inclu...

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

還是先離散化座標,然後用線段樹掃瞄線 其中sum代表被覆蓋過一次的長度,sum2代表被覆蓋過2次及以上的長度。然後注意pushup操作比較麻煩。id sdj22251 prog subset lang c include include include include include include...

hdu 1255 覆蓋的面積 線段樹 掃瞄線

一直想搞線段樹的掃瞄線,這道題算是入門了吧。這題需要用到 離散化,因為座標是浮點數。還有就是線段樹中的掃瞄線的知識,另外,這題需要求重複的面積和,所以在運用線段樹的時候需要更新到葉子節點。每乙個葉子節點儲存的是離散化後長度為1的線段。跟區間更新啥的還是挺像的,就是那些乙個葉子節點表示乙個點,這個是表...