zoukankan      html  css  js  c++  java
  • 线段树+扫面线 矩阵面积并

    扫面线从下往上扫

    将横坐标离散化 用线段树来进行区间更新

    维护两个值cnt 和对应的有效的边(cnt>0)的长度

    当有一个矩阵的下底边扫过的时候 对应的区间cnt+1

    否则 对应的区间cnt-1

    每次计算cnt > 0的区间长度 不会存在cnt < 0 的区间 因为上边扫描过之前必先扫描下底边

    需要注意的是如何处理cnt和 len的关系

    1 void push_up(int root, int l, int r)
    2 {
    3     if (seg[root].flag > 0) seg[root].len = hor[r+1] - hor[l];
    4     else if (l == r) seg[root].len = 0;
    5     else seg[root].len = seg[lson(root)].len + seg[rson(root)].len;
    6 }

    这里对len的计算需要依据 flag(cnt)的值 而线段树并不要维护和、最小值之类的东西 不需要懒标记

    更多关于矩阵面积并的细节

    http://www.cnblogs.com/zhangmingcheng/p/3907072.html

    代码君:

      1 #include <bits/stdc++.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <stdio.h>
      5 #define pb push_back
      6 #define fi first
      7 #define se second
      8 #define lson(r) (r<<1)
      9 #define rson(r) ((r<<1)|1)
     10 
     11 using namespace std;
     12 
     13 typedef long long ll;
     14 
     15 const int MAXN = 1e3+7;
     16 const int MAXV = 507;
     17 const int MAXE = 507;
     18 
     19 struct Seg
     20 {
     21     int flag;
     22     double len;
     23 }seg[MAXN << 2];
     24 struct Line
     25 {
     26     double h, px1, px2;
     27     int x1, x2, flag;
     28     Line () {}
     29     Line (double px1, double px2, double h, int flag) : px1(px1), px2(px2), h(h), flag(flag) {}
     30     bool operator < (Line l) const
     31     {
     32         return h < l.h;
     33     }
     34 }line[MAXN]; 
     35 int n;
     36 double hor[MAXN];
     37 void push_up(int root, int l, int r)
     38 {
     39     if (seg[root].flag > 0) seg[root].len = hor[r+1] - hor[l];
     40     else if (l == r) seg[root].len = 0;
     41     else seg[root].len = seg[lson(root)].len + seg[rson(root)].len;
     42 }
     43 void update(int root, int l, int r, int ul, int ur, int addval)
     44 {
     45     if (l > ur || r < ul) return ;
     46     if (l >= ul && r <= ur)
     47     {
     48         seg[root].flag += addval;
     49         push_up(root, l, r);
     50         return ;
     51     }
     52     int mid = (l+r) >> 1;
     53     update(lson(root), l, mid, ul, ur, addval);
     54     update(rson(root), mid+1, r, ul, ur, addval);
     55     push_up(root, l, r);
     56 }
     57 double query()
     58 {
     59     return seg[1].len;
     60 }
     61 int main()
     62 {
     63     //freopen("in.txt", "r", stdin);
     64     int cas = 1;
     65     while (cin >> n)
     66     {
     67         if (!n) break;
     68         memset(line, 0, sizeof(line));
     69         memset(hor, 0, sizeof(hor));
     70         int num = 0;
     71         for (int i = 0; i < n; i++)
     72         {
     73             double x1, x2, y1, y2;
     74             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
     75             line[num] = Line(x1, x2, y1, 1);
     76             hor[num++] = x1;
     77             line[num] = Line(x1, x2, y2, -1);
     78             hor[num++] = x2;
     79         }        
     80         sort(line, line+num);
     81         sort(hor, hor+num);
     82         int m = unique(hor, hor+num) - hor;
     83         for (int i = 0; i < num; i++)
     84         {
     85             line[i].x1 = lower_bound(hor, hor+m, line[i].px1) - hor;
     86             line[i].x2 = lower_bound(hor, hor+m, line[i].px2) - hor;
     87         }
     88         double prey = -1;
     89         double ans = 0;
     90         for (int i = 0; i < num; i++)
     91         {
     92             if (prey == -1)
     93             {
     94                 prey = line[i].h;
     95                 update(1, 0, m-2, line[i].x1, line[i].x2-1, line[i].flag);
     96                 continue;
     97             }
     98             double det = line[i].h - prey;
     99             double len = query();
    100             update(1, 0, m-2, line[i].x1, line[i].x2-1, line[i].flag);
    101             prey = line[i].h;
    102             ans += len*det;
    103         }
    104         printf("Test case #%d
    Total explored area: %.2f
    
    ", cas++, ans);    
    105     }
    106     return 0;
    107 }
    View Code
  • 相关阅读:
    [03]使用 VS2019 创建 ASP.NET Core Web 程序
    [02]为您的机器配置开发环境
    [01]从零开始学 ASP.NET Core 与 EntityFramework Core 课程介绍
    官宣 ! 52abp_Pro版本低调上线
    2019 年起如何开始学习 ABP 框架系列文章-开篇有益
    IIS配置Url重写实现http自动跳转https的重定向方法(100%解决)
    NanoFabric-ServiceFabric 操作手册
    将 ASP.NET Core 2.0 项目升级至 ASP.NET Core 2.1.3X
    ASP.Net Core 运行错误 Http Error 502.5 解决办法
    52ABP模板 ASP.Net Core 与 Angular的开源实例项目
  • 原文地址:https://www.cnblogs.com/oscar-cnblogs/p/8670337.html
Copyright © 2011-2022 走看看