[HDU1255]覆盖的面积
Description:
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.
Hint:
\(n\le 1000\)
Solution:
扫描线push_up时多讨论几种情况而已
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=1e5+5;
int n,m,tot,cnt,hd[mxn];
double tr[mxn<<2][2];
int cov[mxn<<2];
double x[mxn];
inline int read() {
char c=getchar(); int x=0,f=1;
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
return x*f;
}
inline void chkmax(int &x,int y) {if(x<y) x=y;}
inline void chkmin(int &x,int y) {if(x>y) x=y;}
struct T {
double l,r,h; int val;
friend bool operator < (T x,T y) {
return x.h<y.h;
}
}t[mxn];
void push_up(int p,int l,int r) {
if(cov[p]>1) tr[p][0]=tr[p][1]=x[r+1]-x[l];
else if(cov[p]==1){
tr[p][0]=x[r+1]-x[l];
if(l==r) tr[p][1]=0;
else tr[p][1]=tr[ls][0]+tr[rs][0];
}
else if(l==r) tr[p][0]=tr[p][1]=0;
else {
tr[p][0]=tr[ls][0]+tr[rs][0];
tr[p][1]=tr[ls][1]+tr[rs][1];
}
}
void update(int l,int r,int ql,int qr,int val,int p) {
if(ql<=l&&r<=qr) {
cov[p]+=val;
push_up(p,l,r);
return ;
}
int mid=(l+r)>>1;
if(ql<=mid) update(l,mid,ql,qr,val,ls);
if(qr>mid) update(mid+1,r,ql,qr,val,rs);
push_up(p,l,r);
}
int main()
{
int cas=1; cas=read();
while(cas--) {
n=read();
if(n==0) break;
cnt=tot=0;
for(int i=1;i<=n;++i) {
double a,b,c,d;
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
t[++cnt]=(T){a,c,b,1}; x[cnt]=a;
t[++cnt]=(T){a,c,d,-1}; x[cnt]=c;
}
sort(x+1,x+cnt+1);
sort(t+1,t+cnt+1);
++tot;
for(int i=2;i<=cnt;++i)
if(x[i]!=x[i-1]) x[++tot]=x[i];
memset(tr,0,sizeof(tr));
memset(cov,0,sizeof(cov));
double ans=0;
for(int i=1;i<cnt;++i) {
int l=lower_bound(x+1,x+tot+1,t[i].l)-x;
int r=lower_bound(x+1,x+tot+1,t[i].r)-x-1;
update(1,tot,l,r,t[i].val,1);
ans+=tr[1][1]*(t[i+1].h-t[i].h);
}
printf("%.2lf\n",ans);
}
return 0;
}