• poj 1151 Atlantis(离散+线段树)


    http://poj.org/problem?id=1151

       数据量比较小,不过也是可以先离散坐标,再构建线段树,然后用扫描线在每个关键位置插入/删除线段并进行面积相加。

    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <map>
      5 #include <vector>
      6 
      7 using namespace std;
      8 
      9 map<double, int> id;
     10 vector<double> x;
     11 struct Rect {
     12     double x1, x2, y;
     13     bool end;
     14 } ;
     15 vector<Rect> rect;
     16 const int maxn = 300;
     17 double sum[maxn << 2];
     18 int late[maxn << 2], mx[maxn << 2], mn[maxn << 2];
     19 
     20 bool cmp(const Rect a, const Rect b) {
     21     return a.y < b.y;
     22 }
     23 
     24 void input(int n) {
     25     double x1, y1, x2, y2;
     26     Rect tmp;
     27 
     28     rect.clear();
     29     x.clear();
     30     id.clear();
     31     for (int i = 0; i < n; i++) {
     32         scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
     33         if (x1 > x2) swap(x1, x2);
     34         if (y1 > y2) swap(y1, y2);
     35         tmp.x1 = x1, tmp.x2 = x2, tmp.y = y1, tmp.end = false;
     36         rect.push_back(tmp);
     37         tmp.y = y2, tmp.end = true;
     38         rect.push_back(tmp);
     39         x.push_back(x1);
     40         x.push_back(x2);
     41     }
     42 //    for (int i = 0, endi = x.size(); i < endi; i++) {
     43 //        printf("%.3f\n", x[i]);
     44 //    }
     45     sort(x.begin(), x.end());
     46     sort(rect.begin(), rect.end(), cmp);
     47     x.end() = unique(x.begin(), x.end());
     48 
     49     for (int i = 0, endi = x.size(); i < endi; i++) {
     50         id[x[i]] = i;
     51     }
     52 
     53 //    for (int i = 0, endi = x.size(); i < endi; i++) {
     54 //        printf("%.3f %d\n", x[i], id[x[i]]);
     55 //    }
     56 }
     57 
     58 #define lson l, m, rt << 1
     59 #define rson m, r, rt << 1 | 1
     60 
     61 void up(int rt) {
     62     int ls = rt << 1, rs = rt << 1 | 1;
     63 
     64     mn[rt] = min(mn[ls], mn[rs]);
     65     mx[rt] = max(mx[ls], mx[rs]);
     66     sum[rt] = sum[ls] + sum[rs];
     67 }
     68 
     69 void down(int rt, int l, int r) {
     70     if (late[rt]) {
     71         int ls = rt << 1, rs = rt << 1 | 1;
     72         int m = (l + r) >> 1;
     73 
     74         mx[ls] += late[rt];
     75         mn[ls] += late[rt];
     76         if (mn[ls]) {
     77             sum[ls] = x[m] - x[l];
     78         }
     79         if (!mx[ls]) {
     80             sum[ls] = 0.0;
     81         }
     82         mx[rs] += late[rt];
     83         mn[rs] += late[rt];
     84         if (mn[rs]) {
     85             sum[rs] = x[r] - x[m];
     86         }
     87         if (!mx[rs]) {
     88             sum[rs] = 0.0;
     89         }
     90         late[ls] += late[rt];
     91         late[rs] += late[rt];
     92         late[rt] = 0;
     93     }
     94 }
     95 
     96 void build(int l, int r, int rt) {
     97     sum[rt] = 0.0;
     98     mx[rt] = mn[rt] = late[rt] = 0;
     99     if (r - l == 1) {
    100         return ;
    101     }
    102     int m = (l + r) >> 1;
    103 
    104     build(lson);
    105     build(rson);
    106 }
    107 
    108 void fix(int l, int r, int rt) {
    109     if (r - l == 1 || mn[rt] || mn[rt] == mx[rt]) {
    110         if (!mx[rt]) sum[rt] = 0.0;
    111         if (mn[rt]) sum[rt] = x[r] - x[l];
    112         return ;
    113     }
    114     int m = (l + r) >> 1;
    115 
    116     down(rt, l, r);
    117     fix(lson);
    118     fix(rson);
    119     up(rt);
    120 }
    121 
    122 void update(int L, int R, int k, int l, int r, int rt) {
    123 //    printf("%d %d\n", l, r);
    124     if (L <= l && r <= R) {
    125         mn[rt] += k;
    126         mx[rt] += k;
    127         late[rt] += k;
    128         if (mn[rt]) sum[rt] = x[r] - x[l];
    129         if (!mx[rt]) sum[rt] = 0.0;
    130         if (!mn[rt] && mx[rt]) fix(l, r, rt);
    131 
    132         return ;
    133     }
    134     int m = (l + r) >> 1;
    135 
    136     down(rt, l, r);
    137     if (L < m) update(L, R, k, lson);
    138     if (m < R) update(L, R, k, rson);
    139     up(rt);
    140 }
    141 
    142 double deal(int n) {
    143     double ret = 0.0;
    144 
    145     update(id[rect[0].x1], id[rect[0].x2], 1, 0, x.size(), 1);
    146     for (int i = 1, endi = rect.size(); i < endi; i++) {
    147         ret += sum[1] * (rect[i].y - rect[i - 1].y);
    148 //        printf("%.2f %.2f\n", ret, sum[1]);
    149 //        printf("%d %d\n", id[rect[i].x1], id[rect[i].x2]);
    150 //        printf("%d\n", x.size());
    151         if (rect[i].end) {
    152             update(id[rect[i].x1], id[rect[i].x2], -1, 0, x.size(), 1);
    153         } else {
    154             update(id[rect[i].x1], id[rect[i].x2], 1, 0, x.size(), 1);
    155         }
    156     }
    157 
    158     return ret;
    159 }
    160 
    161 int main() {
    162 //    freopen("in", "r", stdin);
    163     int n, cas = 1;
    164 
    165     while (~scanf("%d", &n) && n) {
    166         input(n);
    167         build(0, x.size(), 1);
    168         printf("Test case #%d\nTotal explored area: %.2f\n\n", cas, deal(n << 1));
    169         cas++;
    170     }
    171 
    172     return 0;
    173 }

    ——written by Lyon

  • 相关阅读:
    url处理函数
    各种排序方法(冒泡,快速,插入,选择),二分查找
    js二叉树,前序/中序/后序(最大最小值,排序)
    vs中nuget命令的用法
    父子页面间调用
    Ubuntu16.04.2 LTS下使用编译安装程序(使用configure、make、 make install)
    windows与虚拟机的linux共享一个文件夹
    Linux下安装nginx
    Linux下安装VSCode
    Ubuntu下安装jdk
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_1151_Lyon.html
Copyright © 2020-2023  润新知