HDU 1255 覆蓋的面積 (線段樹 + 離散化 + 掃描線)

來源:互聯網
上載者:User

標籤:



覆蓋的面積Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4304    Accepted Submission(s): 2139


Problem Description給定平面上若干矩形,求出被這些矩形覆蓋過至少兩次的地區的面積.


 
Input輸入資料的第一行是一個正整數T(1<=T<=100),代表測試資料的數量.每個測試資料的第一行是一個正整數N(1<=N<=1000),代表矩形的數量,然後是N行資料,每一行包含四個浮點數,代表平面上的一個矩形的左上方座標和右下角座標,矩形的上下邊和X軸平行,左右邊和Y軸平行.座標的範圍從0到100000.

注意:本題的輸入資料較多,推薦使用scanf讀入資料.
 
Output對於每組測試資料,請計算出被這些矩形覆蓋過至少兩次的地區的面積.結果保留兩位小數.
 
Sample Input
251 1 4 21 3 3 72 1.5 5 4.53.5 1.25 7.5 46 3 10 730 0 1 11 0 2 12 0 3 1
 
Sample Output
7.630.00本部落格有掃描線方面的詳盡解答,包括這道題目以及一般的掃描線,如果讀者需要請到部落格中http://blog.csdn.net/qq_18661257/article/details/47658191
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace std;typedef long long LL;#define lson rt << 1, l, mid#define rson rt << 1|1, mid + 1, rconst int MAXN = 2000 + 5;int  Col[MAXN << 2], n, cnt, res, T;double X[MAXN << 2], Sum[MAXN << 2],Sum2[MAXN << 2];struct seg {    double l,r,h;    int s;    seg() {}    seg(double l,double r,double h,int s):l(l),r(r),h(h),s(s) {}    bool operator < (const seg & object) const {        return h < object.h;    }} S[MAXN];void pushup(int rt,int l,int r) {    if(Col[rt]) Sum[rt] = X[r + 1] - X[l];    else if(l == r) Sum[rt] = 0;    else Sum[rt] = Sum[rt << 1] + Sum[rt << 1|1];    if(Col[rt] >= 2) Sum2[rt] = X[r + 1] - X[l];    else if(l == r) Sum2[rt] = 0;    else if(Col[rt] == 1) Sum2[rt] = Sum[rt << 1] + Sum[rt << 1|1];    else if(Col[rt] == 0) Sum2[rt] = Sum2[rt << 1] + Sum2[rt << 1|1];}void update(int L, int R, int c,int rt,int l, int r) {    if(L <= l && r <= R) {        Col[rt] += c;        pushup(rt,l,r);        return ;    }    int mid = (l + r) >> 1;    if(L <= mid) update(L, R, c, lson);    if(R > mid) update(L, R, c, rson);    pushup(rt,l,r);}int binary_find(double x) {    int lb = -1,ub = res - 1;    while(ub - lb > 1) {        int mid = (lb + ub) >> 1;        if(X[mid] >= x) ub = mid;        else lb = mid;    }    return ub;}int main() {    scanf("%d", &T);    while(T --) {        scanf("%d", &n);        cnt = res = 0;        for(int i = 0 ; i < n; i ++) {            double a,b,c,d;            scanf("%lf%lf%lf%lf",&a, &b, &c,&d);            S[cnt] = seg(a, c, b, 1);            X[cnt ++] = a;            S[cnt] = seg(a, c, d, -1);            X[cnt ++] = c;        }        sort(X, X + cnt);        sort(S, S + cnt);        res ++;        for(int i = 1; i < cnt; i ++) {            if(X[i] != X[i - 1]) X[res ++] = X[i];        }        memset(Sum, 0, sizeof(Sum));        memset(Col, 0, sizeof(Col));        memset(Sum2,0,sizeof(Sum2));        double ans = 0;        for(int i = 0; i < cnt - 1; i ++) {            int l = binary_find(S[i].l);            int r = binary_find(S[i].r) - 1;//利用[ , ),這個區間性質,左閉右開            update(l, r, S[i].s, 1, 0, res - 1);            ans += Sum2[1] * (S[i + 1].h - S[i].h);        }        printf("%.2lf\n", ans);    }    return 0;}


 

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

HDU 1255 覆蓋的面積 (線段樹 + 離散化 + 掃描線)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.