【题意】给了N个矩形,求出其中被覆盖了两次及两次以上的小矩形的面积总和!
【分析】这里相对于面积并来说,主要是要增加一个统计区间被覆盖了1次及一次以上,以及2次及2次以上的区间长度!
【AC代码】
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 15000;
struct seg{
double y,x1,x2,k;
seg(){}
seg(double y,double x1,double x2,double k):y(y),x1(x1),x2(x2),k(k){}
bool operator<(const seg &rhs) const{
return y<rhs.y;
}
}s[maxn*3];
double Hash[maxn*4];
struct node{
int l,r,flag;
double len1,len2; //len1表示区间被覆盖一次或者以上的长度,len2表示区间被覆盖两次及以上的长度
}Tree[maxn*4];
int binary(int l,int r,double val){
while(l<=r){
int m = (l+r)>>1;
if(Hash[m]==val) return m;
else if(Hash[m]<val) l=m+1;
else r=m-1;
}
return -1;
}
void Build(int l,int r,int rt){
Tree[rt].l=l,Tree[rt].r=r,Tree[rt].flag=0;
Tree[rt].len1=Tree[rt].len2=0;
if(l==r) return ;
int m = (l+r)>>1;
Build(l,m,rt<<1);
Build(m+1,r,rt<<1|1);
}
void Push_Up(int rt){//主要是pushup,按照kuangbin的模板整的
if(Tree[rt].flag>=2){
Tree[rt].len1 = Tree[rt].len2 = Hash[Tree[rt].r+1]-Hash[Tree[rt].l];
}else if(Tree[rt].flag==1){
if(Tree[rt].l==Tree[rt].r){
Tree[rt].len1 = Hash[Tree[rt].r+1]-Hash[Tree[rt].l];
Tree[rt].len2 = 0;
}else{
Tree[rt].len1 = Hash[Tree[rt].r+1]-Hash[Tree[rt].l];
Tree[rt].len2 = Tree[rt<<1].len1+Tree[rt<<1|1].len1;
}
}else{
if(Tree[rt].l==Tree[rt].r){
Tree[rt].len1=Tree[rt].len2=0;
}else{
Tree[rt].len1 = Tree[rt<<1].len1+Tree[rt<<1|1].len1;
Tree[rt].len2 = Tree[rt<<1].len2+Tree[rt<<1|1].len2;
}
}
}
void Update(int L,int R,double val,int rt){
if(L<=Tree[rt].l&&Tree[rt].r<=R){
Tree[rt].flag+=val;
Push_Up(rt);
return ;
}
int m = (Tree[rt].l+Tree[rt].r)>>1;
if(L<=m) Update(L,R,val,rt<<1);
if(m<R) Update(L,R,val,rt<<1|1);
Push_Up(rt);
}
int main(){
int T,n,m,k;
double x1,y1,x2,y2;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
m=0;
while(n--){
//cin>>x1>>y1>>x2>>y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
s[m] = seg(y1,x1,x2,1);
Hash[m++] = x1;
s[m] = seg(y2,x1,x2,-1);
Hash[m++] = x2;
}
sort(Hash,Hash+m);
sort(s,s+m);
k = 1;
Hash[0] = Hash[0];
for(int i=1; i<m; i++) if(Hash[i]!=Hash[i-1]) Hash[k++] = Hash[i];
Build(0,k-1,1);
double ans = 0;
for(int i=0; i<m; i++){
int L = binary(0,k-1,s[i].x1);
int R = binary(0,k-1,s[i].x2)-1;
Update(L,R,s[i].k,1);
ans += Tree[1].len2*(s[i+1].y-s[i].y);
}
printf("%.2lf\n",ans);
}
return 0;
}