• 【POJ 1151】Atlantis


    【原题题面】传送门

    【题面大意】

    给出N个矩形,求矩形的面积并。

    【题解思路】

    线段树扫描线入门题。

    实现的一些细节:

    存边的信息用结构体,根据x的大小排序

    从每段的y值的开始操作

    线段树维护的是的信息

    该段被覆盖了几次

    左端点贡献为1(左端点以后的线段都是正贡献),右端点贡献为-1(右端点以后的值都没有贡献1+-1=0)

    由于区间修改到哪一段是固定的,所以不需要写push

     【code】

    #include<bits/stdc++.h>
    using namespace std;
    #define File ""
    #define ll long long
    inline void file(){
        freopen(File".in","r",stdin);
        freopen(File".out","w",stdout);
    }
    const int mxn = 100+3;
    int n,m,T(0);
    map<double,int> val;
    double raw[mxn<<1];
    struct T{
        int l,r,c;
        double len;
    }tr[mxn<<4];
    struct P{
        double x,y1,y2;
        int k;
        bool operator <(const P t) const {
            return x < t.x;
        }
    }p[mxn<<1];
    #define ls p<<1
    #define rs p<<1|1
    
    inline void B(int p,int l,int r){
        tr[p].l = l,tr[p].r = r;
        tr[p].c = tr[p].len = 0;
        if(l==r) return;
        int mid = l+r >>1;
        B(ls,l,mid),B(rs,mid+1,r);//哈。哈。哈。
    }
    
    inline void U(int p,int l,int r,int k){
        if(l <= tr[p].l && tr[p].r <= r){
            tr[p].len = ((tr[p].c += k) ? raw[tr[p].r+1] - raw[tr[p].l] : 0);
        }
        if(tr[p].l == tr[p].r) return;
        int mid = tr[p].l+tr[p].r >>1;
        if(l <= mid) U(ls,l,r,k);
        if(r > mid) U(rs,l,r,k);
        tr[p].len = (tr[p].c ? raw[tr[p].r+1]-raw[tr[p].l] : tr[ls].len+tr[rs].len);
    }
    
    int main(){
    //    file();
        while(++T){
            scanf("%d",&n);
            if(!n) return 0;
            for(int i = 1; i <= n; ++i){
                double x1,y1,x2,y2;
                scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
                int id = i<<1;
                raw[id-1] = y1,raw[id] = y2;
                p[id-1].x = x1,p[id-1].y1 = y1,p[id-1].y2 = y2,p[id-1].k = 1;
                p[id].x = x2,p[id].y1 = y1,p[id].y2 = y2,p[id].k = -1;
            }
            n <<= 1;
            sort(raw + 1,raw + n + 1);
            int m = unique(raw+1,raw+n+1) - (raw+1);
            for(int i = 1;i <= m; ++i) val[raw[i]] = i;
            sort(p + 1,p + n + 1);
            B(1,1,m-1);
            double ans = 0;
            for(int i = 1;i < n; ++i){
                int y1 = val[p[i].y1],y2 = val[p[i].y2]-1;
                U(1,y1,y2,p[i].k);
                ans += tr[1].len * (p[i+1].x - p[i].x);
            }
            printf("Test case #%d
    ",T);
            printf("Total explored area: %.2f
    ",ans);
            puts("");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    定时器
    javascript之循环保存数值
    Web 前端之HTML和CSS
    [讲解]容斥原理
    [vijos1048]送给圣诞夜的贺卡<DFS剪枝>
    [vijos1145]小胖吃巧克力<概率dp>
    [noip2012]国王游戏<贪心+高精度>
    [codevs3118]高精度除法<高精度>
    [noip2016]组合数问题<dp+杨辉三角>
    [codevs2370]小机房的树<LCA>
  • 原文地址:https://www.cnblogs.com/ve-2021/p/10871137.html
Copyright © 2020-2023  润新知