码迷,mamicode.com
首页 > 其他好文 > 详细

线段树扫描线 求矩阵的覆盖面积

时间:2018-11-27 19:28:08      阅读:269      评论:0      收藏:0      [点我收藏+]

标签:opened   覆盖   isp   img   namespace   spl   c++   void   upd   

题意:给出几个矩阵求这些矩阵覆盖的面积:

给出左上角与右下角

Sample Input

2
0 5 4 1
2 4 6 2

Sample Output

20

技术分享图片
#include<bits/stdc++.h>
#define LL long long
#define lson l, m, rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxn = 5e3 + 10;
const int Base = 1e8;
int add[maxn];
int x[maxn<<2];
long long sum[maxn<<2];
struct Node{
    int flag;
    int l, r, h;
    Node(){};
    Node(int L, int R, int H, int F):l(L),r(R),h(H),flag(F){};
    bool operator < (const Node & rhs) const{
        return this->h < rhs.h;
    };
}s[maxn];
inline void pushup(int rt, int l, int r)
{
    if(add[rt]) sum[rt] = x[r+1] - x[l];/// 这里每一个 l 和 r 是离散化后的值
                                        /// 所以应当代入 x 数组来获取真实值
    else if(l == r) sum[rt] = 0;
    else sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}

inline void update(int L, int R, int c, int l, int r, int rt)
{
    int m;
    if(L <= l && r <= R){
        add[rt] += c;
        pushup(rt, l, r);
        return ;
    }
    m = (l+r)>>1;
    if(L <= m) update(L, R, c, lson);
    if(R >  m) update(L, R, c, rson);
    pushup(rt, l, r);
}

int main(void)
{
    int n;
    scanf("%d", &n);
    int x1, x2, y1, y2;
    int num = 0;
    for(int i=0; i<n; i++){
        scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
        x1 += Base, x2 += Base, y1 += Base, y2 += Base;/// 因为有负数坐标的存在,所以需要加上一个基数
        x[num] = x1;/// 记录所有出现的横坐标的值,方便离散化
        s[num++] = Node(x1, x2, y1, 1); /// 将所有的横边(与x轴平行)以及其高度存储起来
        x[num] = x2;
        s[num++] = Node(x1, x2, y2, -1);/// 顶边 flag == 1 而底边 flag == -1 是为了方便
                                        /// 从上到下扫描的时候做到,计入及删除这个矩形操作
    }
    sort(x, x+num);
    sort(s, s+num);
    int idx = std::unique(x, x+num) - x;/// 离散化横坐标
    int L, R;
    long long ans = 0;/// Attention !!!
    for(int i=0; i<num-1; i++){
        L = lower_bound(x, x+idx, s[i].l) - x;/// 找出线段树应当更新的左右界,注意是使用离散化后的值
        R = lower_bound(x, x+idx, s[i].r) - x - 1;
        update(L,R,s[i].flag,0,idx-1,1);/// 根据 flag 来确定是要删除还是添加操作
        ans+=(sum[1]*(1LL*s[i+1].h-1LL*s[i].h));/// 最后用当前存在的横坐标的总和去乘高度就是面积了,累加起来
    }
    printf("%lld\n", ans);
    return 0;
}
View Code

 

线段树扫描线 求矩阵的覆盖面积

标签:opened   覆盖   isp   img   namespace   spl   c++   void   upd   

原文地址:https://www.cnblogs.com/shuaihui520/p/10028062.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!