题目链接 :HDU 3265 Posters
题意:给出N,有N组数据,每组4个点,表示一个有洞(矩形)的矩形布,求这些布的面积并。
将有洞的矩形布分割成4个小矩形,再扫描线处理处面积。
注意:结构体数组的大小。
左黄:(x1,y1) (x3,y2)
右黄:(x4,y1) (x2,y2)
下蓝:(x3,y1) (x4,y3)
上蓝:(x3,y4) (x4,y2)
AC代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<set>
#define ll __int64
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const ll maxn=50010;
struct Seg
{
ll l,r,h;
ll flag;
Seg(){}
Seg(ll a,ll b,ll c,ll d):l(a),r(b),h(c),flag(d){}
bool operator<(const Seg &hh) const
{
return h<hh.h;
}
};
struct Seg s[maxn<<3];
ll cover[maxn<<2],sum[maxn<<2];
ll x[maxn<<2];
void PushUp(ll rt,ll l,ll r)
{
if(cover[rt]) sum[rt]=x[r+1]-x[l];
else if(l==r) sum[rt]=0;
else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void Update(ll L,ll R,ll f,ll l,ll r,ll rt)
{
if(L<=l && r<=R)
{
cover[rt]+=f;
PushUp(rt,l,r);
return ;
}
ll m=(l+r)>>1;
if(R<=m) Update(L,R,f,lson);
else if(L>m) Update(L,R,f,rson);
else
{
Update(L,R,f,lson);
Update(L,R,f,rson);
}
PushUp(rt,l,r);
}
ll Bin(ll k,ll n,ll x[])
{
ll l,r,m;
l=0,r=n-1;
while(l<=r)
{
m=(l+r)>>1;
if(x[m]==k) return m;
else if(x[m]>k) r=m-1;
else l=m+1;
}
return -1;
}
set<ll> ss;
set<ll>::iterator it;
int main()
{
ll n;
ll i;
while(scanf("%I64d",&n)!=EOF,n)
{
ll m=0;
ss.clear();
for(i=0;i<n;i++)
{
ll x1,x2,x3,x4,y1,y2,y3,y4;
scanf("%I64d %I64d %I64d %I64d",&x1,&y1,&x2,&y2);//poster
scanf("%I64d %I64d %I64d %I64d",&x3,&y3,&x4,&y4);//hole
s[m++]=Seg(x1,x3,y1,1); //(x1,y1) (x3,y2)
s[m++]=Seg(x1,x3,y2,-1);
s[m++]=Seg(x4,x2,y1,1); //(x4,y1) (x2,y2)
s[m++]=Seg(x4,x2,y2,-1);
ss.insert(x1);
ss.insert(x3);
ss.insert(x4);
ss.insert(x2);
s[m++]=Seg(x3,x4,y1,1); //(x3,y1) (x4,y3)
s[m++]=Seg(x3,x4,y3,-1);
s[m++]=Seg(x3,x4,y4,1); //(x3,y4) (x4,y2)
s[m++]=Seg(x3,x4,y2,-1);
}
sort(s,s+m);
ll k=0;
for(it=ss.begin();it!=ss.end();it++)
x[k++]=*it;
memset(cover,0,sizeof cover);
memset(sum,0,sizeof sum);
ll ans=0;
for(i=0;i<m-1;i++)
{
ll l=Bin(s[i].l,k,x);
ll r=Bin(s[i].r,k,x)-1;
if(l<=r) Update(l,r,s[i].flag,0,k-1,1);
ans+=sum[1]*(s[i+1].h-s[i].h);
}
printf("%I64d\n",ans);
}
return 0;
}