zoukankan      html  css  js  c++  java
  • poj1151 Atlantis (线段树+扫描线+离散化)

    有点难,扫描线易懂,离散化然后线段树处理有点不太好理解。

    因为这里是一个区间,所有在线段树中更新时,必须是一个长度大于1的区间才是有效的,比如[l,l]这是一根线段,而不是区间了。

    AC代码

    #include <stdio.h>
    #include <map>
    #include <vector>
    #include <algorithm>
    using namespace std;
    const int maxn = 200 + 5;
    
    struct Line{
        double x, y1, y2;
        int flag;
        Line(double a, double b, double c, int d) {
            x = a; y1 = b; y2 = c; flag = d;
        }
        bool operator < (const Line& a) const {
            return x < a.x;
        }
    };
    
    vector<Line> line;
    map<double, int> Hash;
    vector<double> y;
    
    double p[maxn << 2];    // 区间长度
    int covers[maxn << 2];  // 覆盖次数
    double len[maxn << 2];  // 覆盖长度
    
    void buildTree(int o, int l, int r) {
        len[o] = covers[o] = 0;
        p[o] = y[r] - y[l];
        if(l + 1 != r) {
            int m = (l+r) / 2;
            buildTree(o*2, l, m);
            buildTree(o*2+1, m, r);
        }
    }
    
    int ul, ur; 
    void update(int o, int l, int r, int f) {
        if(l+1 == r) {
            covers[o] += f;
            if(covers[o] == 0) len[o] = 0;
            else len[o] = p[o]; 
        } 
        else {
            int m = (l+r) / 2;
            if(ul < m) update(o*2, l, m, f);
            if(m < ur) update(o*2+1, m, r, f);
            // pushUp
            len[o] = len[o*2] + len[o*2+1];
        }
    }
    
    int main() {
        int n, kase = 1;
        while(scanf("%d", &n) == 1 && n) {
            Hash.clear(); line.clear(); y.clear();
            double x1, y1, x2, y2;
            for(int i = 0; i < n; i++) {
                scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
                line.push_back(Line(x1, y1, y2, 1));
                line.push_back(Line(x2, y1, y2, -1));
                y.push_back(y1);
                y.push_back(y2);
            }
            
            sort(line.begin(), line.end());
            sort(y.begin(), y.end());
            y.erase(unique(y.begin(), y.end()), y.end());
            for(int i = 0; i < (int)y.size(); i++) {
                Hash[y[i]] = i;
            }
            
            buildTree(1, 0, y.size()-1);
            double ans = 0;
            for(int i = 0; i < line.size(); i++) {
                if(i > 0) ans += (line[i].x - line[i-1].x) * len[1];
                ul = Hash[line[i].y1]; ur = Hash[line[i].y2];
                update(1, 0, y.size()-1, line[i].flag);
            }
            printf("Test case #%d
    Total explored area: %.2f
    
    ", kase++, ans);
        }
        return 0;
    }

    如有不当之处欢迎指出!

  • 相关阅读:
    小程序模板template问题记录
    datepicker 组件 的坑
    js实现 throttle 和 debounce
    vuex简单使用
    webpack 打包图片 缺失问题
    invalid prop `current` of type `string` supplied to `pagination`, expected `
    HTML5自定义属性之data-*
    vue组件传值方式介绍
    解决github.com 打不开问题
    git密令使用
  • 原文地址:https://www.cnblogs.com/flyawayl/p/8868211.html
Copyright © 2011-2022 走看看