题意:
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.
思路:
参考大佬
直到要改这个pushup函数,但理解不够改不出,参考了大佬的博客。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson l, mid, root<<1
#define rson mid, r, root<<1|1
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long LL;
const int maxn = 1000+5;
double X[maxn<<1];
struct Edge{
double l, r, h;
int f;
Edge(){}
Edge(double a, double b, double c, int d):l(a),r(b),h(c),f(d){}
bool operator < (const Edge& rhs) const{
return h < rhs.h;
}
}edges[maxn<<2];
struct Node{
int cover;
double len1, len2;
}Tree[maxn<<3];
void push_up(int l, int r, int root){
if(Tree[root].cover > 0) Tree[root].len1 = X[r] - X[l];
else if(l+1 == r) Tree[root].len1 = 0;
else Tree[root].len1 = Tree[root<<1].len1 + Tree[root<<1|1].len1;
if(Tree[root].cover > 1) Tree[root].len2 = X[r] - X[l];
else if(l+1 == r) Tree[root].len2 = 0;
else if(Tree[root].cover == 1) Tree[root].len2 = Tree[root<<1].len1 + Tree[root<<1|1].len1;
else Tree[root].len2 = Tree[root<<1].len2 + Tree[root<<1|1].len2;
}
void Stree_build(int l, int r, int root){
Tree[root].cover = Tree[root].len1 = Tree[root].len2 = 0;
if(l+1 == r) return;
int mid = (l+r) >> 1;
Stree_build(lson);
Stree_build(rson);
}
void update(int la, int rb, int l, int r, int root, int val){
if(la > r||rb < l) return;
if(la <= l&&rb >= r){
Tree[root].cover+= val;
push_up(l, r, root);
return;
}
if(l+1 == r) return;
int mid = (l+r) >> 1;
if(la <= mid) update(la, rb, lson, val);
if(rb > mid) update(la, rb, rson, val);
push_up(l, r, root);
}
int main()
{
freopen("in.txt","r",stdin);
int T, n; scanf("%d",&T);
double x1,y1,x2,y2;
while(T--){
scanf("%d",&n);
int tot = 0;
for(int i = 0; i < n; ++i){
scanf("%lf%lf%lf%lf", &x1,&y1,&x2,&y2);
edges[++tot] = Edge(x1, x2, y1, 1); X[tot] = x1;
edges[++tot] = Edge(x1, x2, y2, -1); X[tot] = x2;
}
sort(edges+1, edges+tot+1);
sort(X+1, X+tot+1);
int k = 1;
for(int i = 2; i <= tot; ++i) if(X[i] != X[i-1]) X[++k] = X[i];
Stree_build(1, k, 1);
double ans = 0;
for(int i = 1; i < tot; ++i){
int l = lower_bound(X+1, X+k+1, edges[i].l) - X;
int r = lower_bound(X+1, X+k+1, edges[i].r) - X;
update(l, r, 1, k, 1, edges[i].f);
ans+= (edges[i+1].h - edges[i].h) * Tree[1].len2;
}
printf("%.2lf\n", ans);
}
return 0;
}