• [Codevs] 矩形面积求并


    http://codevs.cn/problem/3044/

    线段树扫描线矩形面积求并

    基本思路就是将每个矩形的长(平行于x轴的边)投影到线段树上

    下边+1,上边-1;

    然后根据线段树的权值和与相邻两条边的差值(高度差)求出相应的矩形面积

    #include <bits/stdc++.h>
    
    using namespace std;
    const int N = 1100;
    
    #define DB double
    
    int F[N << 2];
    DB W[N << 2], X[N];
    struct Node {
        DB x_1, x_2, h; int how;
        Node() {};
        Node(DB x_1_, DB x_2_, DB h_, int how_) {x_1 = x_1_; x_2 = x_2_; h = h_; how = how_;}
    }A[N];
    
    bool cmp(Node a, Node b) {return a.h < b.h;}
    
    inline int Find(DB num, int n) {
        int L = 1, R = n, Mid;
        while(L <= R) {
            Mid = (L + R) >> 1;
            if(X[Mid] == num) return Mid;
            else if(X[Mid] < num) L = Mid + 1;
            else R = Mid - 1;
        }
    }
    
    #define lson jd << 1
    #define rson jd << 1 | 1 
    
    void Pushup(int jd, int l, int r) {
        if(F[jd]) W[jd] = X[r + 1] - X[l];
        else if(l == r) W[jd] = 0;
        else W[jd] = W[lson] + W[rson];
    } 
    
    void Sec_G(int l, int r, int jd, int x, int y, int yj) {
        if(x <= l && r <= y) {
            F[jd] += yj;
            Pushup(jd, l, r);
            return ;
        }
        int mid = (l + r) >> 1;
        if(x <= mid) Sec_G(l, mid, lson, x, y, yj);
        if(y > mid)  Sec_G(mid + 1, r, rson, x, y, yj);
        Pushup(jd, l, r);
    }
    
    int main() {
        while(1) {
            int n;
            cin >> n;
            int js = 0;
            if(!n) break;
            memset(F, 0, sizeof F);
            memset(W, 0, sizeof W);
            for(int i = 1; i <= n; i ++) {
                DB x_1, x_2, y_1, y_2;                                                                                 
                scanf("%lf%lf%lf%lf", &x_1, &y_1, &x_2, &y_2);
                A[++ js] = Node(x_1, x_2, y_1, 1);
                X[js] = x_1;
                A[++ js] = Node(x_1, x_2, y_2, -1);
                X[js] = x_2;
            }
            sort(X + 1, X + js + 1);
            sort(A + 1, A + js + 1, cmp);
            int k = 1;
            for(int i = 2; i <= js; i ++) if(X[i] != X[i + 1]) X[++ k] = X[i];
            DB Answer = 0;
            for(int i = 1; i < js;  i ++) {
                int l = Find(A[i].x_1, k), r = Find(A[i].x_2, k) - 1;
                Sec_G(1, k, 1, l, r, A[i].how);
                Answer += W[1] * (A[i + 1].h - A[i].h);
            }
            printf("%.2lf
    ", Answer);
        }
        return 0;
    }
  • 相关阅读:
    文件目录T位
    改变文件权限的用户身份
    改变进程打开文件默认权限检查方式
    新建文件的UID和GID
    进程的用户ID
    centos7使用无线wifi连接
    2.8. 创建 NSManagedObject 的子类 (Core Data 应用程序实践指南)
    2.7. 属性的各种设置选项(Core Data 应用程序实践指南)
    2.6. 类型(Core Data 应用程序实践指南)
    2.5. Integer 16 、Integer 32、Integer 64(Core Data 应用程序实践指南)
  • 原文地址:https://www.cnblogs.com/shandongs1/p/8543017.html
Copyright © 2020-2023  润新知