一道挺簡單的題,讓我折騰了許久。主要卡在了更新節點後維護父親節點上。後來思路明確了就很容易了。
節點資訊:
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的線段。跟區間更新啥的還是挺像的,就是那些乙個葉子節點表示乙個點,這個是表...