题意:
求矩形面积并,有个变化就是每个矩形里都有一个矩形的洞。
思路:
每个矩形有个空心,那就把每个矩形分成4个小矩形。转化为矩形的面积并。
#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 = 50000+5;
int X[maxn<<2];
struct Edge{
int l, r, h, f;
Edge(){}
Edge(int a, int b, int c, int d):l(a),r(b),h(c),f(d){}
bool operator < (const Edge& rhs) const{
return h < rhs.h;
}
}edges[maxn<<3];
struct Node{
int cover, len;
}Tree[maxn<<5];
void push_up(int l, int r, int root){
if(Tree[root].cover > 0) Tree[root].len = X[r] - X[l];
else if(l+1 == r) Tree[root].len = 0;
else Tree[root].len = Tree[root<<1].len + Tree[root<<1|1].len;
}
void Stree_build(int l, int r, int root){
Tree[root].cover = Tree[root].len = 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 n;
int x1, y1, x2, y2, x11, y11, x22, y22;
while(scanf("%d",&n) == 1&&n){
int tot = 1, xc = 1;
for(int i = 1; i <= n; ++i){
scanf("%d%d%d%d%d%d%d%d",&x1, &y1, &x2, &y2, &x11, &y11, &x22, &y22);
X[xc] = x1; X[xc+1] = x2; X[xc+2] = x11; X[xc+3] = x22;
xc+= 4;
edges[tot] = Edge(x1, x2, y1, 1); edges[tot+1] = Edge(x1, x2, y11, -1);
edges[tot+2] = Edge(x1, x2, y22, 1); edges[tot+3] = Edge(x1, x2, y2, -1);
edges[tot+4] = Edge(x1, x11, y11, 1); edges[tot+5] = Edge(x1, x11, y22, -1);
edges[tot+6] = Edge(x22, x2, y11, 1); edges[tot+7] = Edge(x22, x2, y22, -1);
tot+= 8;
}
--xc;--tot;
//printf("xc = %d, tot= %d\n",xc,tot);
sort(edges+1, edges+tot+1);
sort(X+1, X+xc+1);
int k = 1;
for(int i = 2; i <= xc; ++i) if(X[i] != X[i-1]) X[++k] = X[i];
Stree_build(1, k, 1);
LL 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+= (LL)(edges[i+1].h - edges[i].h) * Tree[1].len;
}
printf("%lld\n", ans);
}
return 0;
}