• HDU1255


    Description

    给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.

    思路

    和单纯的求面积非常相似,用len来储存被覆盖到两次以上的区间长度。

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    #define endl '
    '
    typedef long long ll;
    
    const int N = 3000;
    
    struct snode {
        double x, y1, y2;
        int flag;
        
    };
    
    bool cmp(const snode &a, const snode &b) {
        return a.x < b.x;
    }
    
    struct tnode {
        double sum, l, r, len;
    };
    
    tnode st[N << 2];
    snode seg[N];
    double num[N];
    int lazy[N << 2];
    
    void pushup(int rt) {
        if(lazy[rt] > 0) {
            st[rt].sum = st[rt].r - st[rt].l;
            if(lazy[rt] > 1) st[rt].len = st[rt].sum;
            else st[rt].len = st[rt << 1].sum + st[rt << 1 | 1].sum;
        } else {
            st[rt].sum = st[rt << 1].sum + st[rt << 1 | 1].sum;
            st[rt].len = st[rt << 1].len + st[rt << 1 | 1].len;
        }
    
    }
    
    void update(double L, double R, int rt, int flag) {
        if(L == st[rt].l && R == st[rt].r) {
            lazy[rt] += flag;
            pushup(rt);
            return ;
        }
        if(st[rt << 1].r > L) //>而不是>=?不能等于,否则长度为0,会进入死循环。
            update(L, min(R, st[rt << 1].r), rt << 1, flag);
        if(st[rt << 1 | 1].l < R) 
            update(max(L, st[rt << 1 | 1].l), R, rt << 1 | 1, flag);
        pushup(rt);
    }
    
    void build(int lef, int rig, int rt) {
        if(rig - lef > 1) { //由于mid公用,所以>1就可以
            int mid = (lef + rig) / 2;
            st[rt].l = num[lef];
            st[rt].r = num[rig];
            build(lef, mid, rt << 1);
            build(mid, rig, rt << 1 | 1); //mid而不是mid+1?因为是线段,头尾需要相连,否则会少值
            pushup(rt);
        } else {
            st[rt].l = num[lef];
            st[rt].r = num[rig];
            st[rt].sum = 0;
            st[rt].len = 0;
        }
    }
    
    
    int main() {
        
        //ios::sync_with_stdio(false);
        int n;
        int t;
        scanf("%d", &t);
        while(t--) {
            scanf("%d", &n);
            if(!n) break;
            for(int i = 0; i < n; i++) {
                double x1, x2, y1, y2;
                scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
                seg[i].x = x1; seg[i].y1 = y1; seg[i].y2 = y2; 
                seg[i].flag = 1;
                seg[i + n].x = x2; seg[i + n].y1 = y1; seg[i + n].y2 = y2; 
                seg[i + n].flag = -1;
    
                num[i + 1] = y1;
                num[i + 1 + n] = y2;
            }
            sort(num + 1, num + 1 + (2 * n));
            sort(seg, seg + 2 * n, cmp);
            memset(lazy, 0, sizeof lazy);
            build(1, 2 * n, 1);
            double ans = 0;
            update(seg[0].y1, seg[0].y2, 1, seg[0].flag);
            for(int i = 1; i < 2 * n; i++) {
                ans += (seg[i].x - seg[i - 1].x) * st[1].len;
                //cout << st[1].len << endl;
                update(seg[i].y1, seg[i].y2, 1, seg[i].flag);
                //cout << seg[i].x << " " << seg[i].y1 << " " << seg[i].y2 << endl;
            }
            printf("%.2lf
    ", ans);
            //printf("Total explored area: %.2lf
    
    ", ans);
        }
    }
    
  • 相关阅读:
    Codeforces 451A Game With Sticks
    POJ 3624 Charm Bracelet
    POJ 2127 Greatest Common Increasing Subsequence
    POJ 1458 Common Subsequence
    HDU 1087 Super Jumping! Jumping! Jumping!
    HDU 1698
    HDU 1754
    POJ 1724
    POJ 1201
    CSUOJ 1256
  • 原文地址:https://www.cnblogs.com/limil/p/12741560.html
Copyright © 2020-2023  润新知