题意:给出几个矩阵求这些矩阵覆盖的面积:
给出左上角与右下角
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; }
原文地址:https://www.cnblogs.com/shuaihui520/p/10028062.html
时间: 2024-11-10 09:46:24