• hdu 1542 线扫描+线段树(离散化) 求覆盖面积/周长


    // hdu1542 

    // 线扫瞄思想结合线段树求覆盖面积问题,也能求周长。具体如何线扫瞄 下面参考博客里面有

    // 直接百度学的(想破脑壳也只能是wa或者tle)

    // 参考博客  HDU 1542 Atlantis(线段树:扫描线)

    // 不能算抄。。。结合了多方代码得出我喜欢的写法。。。离散化区间问题只停留在听懂的层面上, 之前并查集区间离散化也是囫囵吞枣的学,不能这样啊( ఠൠఠ )ノ

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define L k<<1
     4 #define R k<<1|1
     5 #define mid (tree[k].l+tree[k].r)>>1
     6 using namespace std;
     7 typedef long long ll;
     8 const int MAXN = 200+5;
     9 
    10 double X[MAXN];
    11 struct Edge {
    12     double l, r;
    13     double h;
    14     int f;
    15     Edge() {}
    16     Edge(double l, double r, double h, int f):l(l),r(r),h(h),f(f) {}
    17     bool operator < (const Edge &a) const {
    18         return h < a.h;
    19     }
    20 }edge[MAXN];
    21 //Edge ;
    22 
    23 struct segmemt_tree {
    24     int l, r;// 左右区间端点
    25     int cover;
    26     double len;
    27 }tree[4*MAXN+1];
    28 
    29 inline void build(int k, int l, int r) {
    30     tree[k].l = l; tree[k].r = r;
    31     tree[k].cover = tree[k].len = 0;
    32     if(l == r) return ;
    33     int m = mid;
    34     build(L, l, m);
    35     build(R, m+1, r);
    36 }
    37 
    38 inline void push_up(int k) {
    39     if(tree[k].cover) tree[k].len = X[tree[k].r+1] - X[tree[k].l];
    40     else if(tree[k].l == tree[k].r) tree[k].len = 0;
    41     else tree[k].len = tree[L].len + tree[R].len;
    42 }
    43 
    44 inline void update(int k, int x, int y, int cover) {
    45     if(tree[k].l >= x && tree[k].r <= y) {
    46         tree[k].cover += cover;
    47         push_up(k);
    48         return ;
    49     }
    50     int m = mid;
    51     if(x <= m) update(L, x, y, cover);
    52     if(y > m) update(R, x, y, cover);
    53     push_up(k);
    54 }
    55 
    56 int main() {
    57     int n, Case = 0;
    58     while(scanf("%d", &n) == 1 && n) {
    59         int cnt = 0;
    60         double x1, y1, x2, y2;
    61         for(int i = 0; i != n; ++i) {
    62             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
    63             X[cnt] = x1;
    64             edge[cnt++] = Edge(x1, x2, y1, 1);
    65             X[cnt] = x2;
    66             edge[cnt++] = Edge(x1, x2, y2, -1);
    67         }
    68         sort(X, X+cnt);
    69         sort(edge, edge+cnt);
    70         int k = unique(X, X+cnt) - X;
    71         build(1, 0, k-1);
    72         double sum = 0;
    73         for(int i = 0; i != cnt; ++i) {
    74             int l = lower_bound(X, X+k, edge[i].l) - X;
    75             int r = lower_bound(X, X+k, edge[i].r) - X - 1;
    76             update(1, l, r, edge[i].f);
    77             sum += (edge[i+1].h - edge[i].h) * tree[1].len;
    78         }
    79         printf("Test case #%d
    ", ++Case);
    80         printf("Total explored area: %.2lf
    
    ", sum);
    81     }
    82     return 0;
    83 }

    // hdu 1255上一题升级版(求覆盖两次和两次以上的面积)

     1 /*
     2  * @Author: pupil-XJ
     3  * @Date: 2019-10-10 00:09:46
     4  * @LastEditTime: 2019-10-10 11:47:20
     5  */
     6 #include<cstdio>
     7 #include<algorithm>
     8 #define L k<<1
     9 #define R k<<1|1
    10 #define mid (tree[k].l+tree[k].r)>>1
    11 using namespace std;
    12 const int MAXN = 2000+5;
    13 
    14 double x[MAXN];
    15 struct Edge {
    16     double l, r, h;
    17     int f;
    18     Edge(){}
    19     Edge(double l, double r, double h, int f):l(l),r(r),h(h),f(f){}
    20     bool operator < (const Edge &a) const {
    21         return h < a.h;
    22     }
    23 } edge[MAXN];
    24 
    25 struct segmemt_tree {
    26     int l, r, cover;
    27     double len1, len2;// len1(cover once) len2(cover over than once)
    28 } tree[4*MAXN+1];
    29 
    30 inline void build(int k, int l, int r) {
    31     tree[k].l = l; tree[k].r = r;
    32     tree[k].cover = tree[k].len1 = tree[k].len2 = 0;
    33     if(l == r) return ;
    34     int m = mid;
    35     build(L, l, m);
    36     build(R, m+1, r);
    37 }
    38 
    39 inline void push_up(int k) {
    40     // update->len1
    41     if(tree[k].cover) tree[k].len1 = x[tree[k].r+1] - x[tree[k].l];
    42     else if(tree[k].l == tree[k].r) tree[k].len1 = 0;
    43     else tree[k].len1 = tree[L].len1 + tree[R].len1;
    44     // update->len2
    45     if(tree[k].cover > 1) tree[k].len2 = x[tree[k].r+1] - x[tree[k].l];
    46     else if(tree[k].l == tree[k].r) tree[k].len2 = 0;
    47     else if(tree[k].cover == 1) tree[k].len2 = tree[L].len1 + tree[R].len1;
    48     else tree[k].len2 = tree[L].len2 + tree[R].len2;
    49 }
    50 
    51 inline void update(int k, int x, int y, int f) {
    52     if(tree[k].l >= x && tree[k].r <= y) {
    53         tree[k].cover += f;
    54         push_up(k);
    55         return ;
    56     }
    57     int m = mid;
    58     if(x <= m) update(L, x, y, f);
    59     if(y > m) update(R, x, y, f);
    60     push_up(k);
    61 }
    62 
    63 int main() {
    64     int T, n;
    65     double x1, y1, x2, y2;
    66     scanf("%d", &T);
    67     while(T--) {
    68         scanf("%d", &n);
    69         int cnt = 0;
    70         for(int i = 0; i != n; ++i) {
    71             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
    72             x[cnt] = x1;
    73             edge[cnt++] = Edge(x1, x2, y1, 1);
    74             x[cnt] = x2;
    75             edge[cnt++] = Edge(x1, x2, y2, -1);
    76         }
    77         sort(x, x+cnt);
    78         sort(edge, edge+cnt);
    79         int k = unique(x, x+cnt) - x;
    80         
    81         build(1, 0, k-1);
    82         double sum = 0;
    83         for(int i = 0; i != cnt; ++i) {
    84             int l = lower_bound(x, x+k, edge[i].l) - x;
    85             int r = lower_bound(x, x+k, edge[i].r) - x - 1;
    86             update(1, l, r, edge[i].f);
    87             sum += (edge[i+1].h - edge[i].h) * tree[1].len2;
    88         }
    89         printf("%.2lf
    ", sum);
    90     }
    91     return 0;
    92 }
    View Code

     // poj 1177 求覆盖周长

    推荐博客: ->

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<algorithm>
     4 #define L k<<1
     5 #define R k<<1|1
     6 #define mid (tree[k].l+tree[k].r)>>1
     7 using namespace std;
     8 const int MAXN = 10000+5;
     9 
    10 int x[MAXN];
    11 struct Edge {
    12     int l, r, h;
    13     int f;
    14     Edge(){}
    15     Edge(int l, int r, int h, int f):l(l),r(r),h(h),f(f){}
    16     bool operator < (const Edge &a) const {
    17         return h < a.h;
    18     }
    19 } edge[MAXN];
    20 
    21 struct segmemt_tree {
    22     int l, r, cover, num;
    23     int lc, rc;
    24     int len;
    25 } tree[4*MAXN+1];
    26 
    27 inline void build(int k, int l, int r) {
    28     tree[k].l = l; tree[k].r = r;
    29     tree[k].cover = tree[k].num = tree[k].lc = tree[k].rc = tree[k].len = 0;
    30     if(l == r) return;
    31     int m = mid;
    32     build(L, l, m);
    33     build(R, m+1, r);
    34 }
    35 
    36 inline void push_up(int k) {
    37     if(tree[k].cover) {
    38         tree[k].len = x[tree[k].r+1] - x[tree[k].l];
    39         tree[k].lc = tree[k].rc = 1;
    40         tree[k].num = 1;
    41     }
    42     else if(tree[k].l == tree[k].r) {
    43         tree[k].len = 0;
    44         tree[k].lc = tree[k].rc = 0;
    45         tree[k].num = 0;
    46     }
    47     else {
    48         tree[k].len = tree[L].len + tree[R].len;
    49         tree[k].lc = tree[L].lc; tree[k].rc = tree[R].rc;
    50         tree[k].num = tree[L].num + tree[R].num - (tree[L].rc&tree[R].lc);
    51     }
    52 }
    53 
    54 inline void update(int k, int x, int y, int f) {
    55     if(tree[k].l >= x && tree[k].r <= y) {
    56         tree[k].cover += f;
    57         push_up(k);
    58         return ;
    59     }
    60     int m = mid;
    61     if(x <= m) update(L, x, y, f);
    62     if(y > m) update(R, x, y, f);
    63     push_up(k);
    64 }
    65 
    66 int main() {
    67     int n, cnt = 0;
    68     scanf("%d", &n);
    69     int x1, x2, y1, y2;
    70     for(int i = 0; i != n; ++i) {
    71         scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
    72         x[cnt] = x1;
    73         edge[cnt++] = Edge(x1, x2, y1, 1);
    74         x[cnt] = x2;
    75         edge[cnt++] = Edge(x1, x2, y2, -1);
    76     }
    77     sort(x, x+cnt);
    78     sort(edge, edge+cnt);
    79     int k = unique(x, x+cnt) - x;
    80 
    81     build(1, 0, k-1);
    82     int sum = 0, last = 0;
    83     for(int i = 0; i != cnt; ++i) {
    84         int l = lower_bound(x, x+k, edge[i].l) - x;
    85         int r = lower_bound(x, x+k, edge[i].r) - x - 1;
    86         update(1, l, r, edge[i].f);
    87         sum += abs(tree[1].len - last);
    88         sum += (edge[i+1].h - edge[i].h)*2*tree[1].num;
    89         last = tree[1].len;
    90     }
    91     printf("%d
    ", sum);
    92     return 0;
    93 }

    12ewqewqeqweewqqwe

  • 相关阅读:
    【树状数组·进阶篇】树状数组实现平衡树(树状数组上二分)
    【$Polya$定理·应用篇】$Polya$定理的几种模型简介
    【博弈论·入门篇】$SG$函数基础入门
    关于win10安装CPC专利软件以及win10安装office2003
    部署react项目到服务器,配置nginx的伪静态
    中等 39. 组合总和 (递归,去除数组中重复的元素)
    jsonp策略,cors响应头,实现跨域
    文档-关于这次参加比赛写文档的总结
    前端-关于这次暑假的和大家一起做项目的总结
    servlet获取前台数据或者返回前台数据乱码的问题
  • 原文地址:https://www.cnblogs.com/pupil-xj/p/11643843.html
Copyright © 2020-2023  润新知