这是09宁波Regional Contest 一道计算几何的题目。题目还是比较简单的。大致也是求矩形面积的并。但是有一点点的变化。关键是代码稍微有点长,其实题目很简单。
解决方法还得典型的离散化+线段树+扫描线。
代码如下:
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 50002
struct SegTree
{
int l,r,mid;
int c;
__int64 m;
}tree[12*N];
struct Line
{
int x,y1,y2;
bool flag;
}line[8*N];
int ty[4*N],y[4*N];
int num;
bool cmp(Line a,Line b)
{
return a.x<b.x;
}
void BulidTree(int root,int l,int r) //建立线段树
{
tree[root].l=l;
tree[root].r=r;
tree[root].m=0;
tree[root].c=0;
if(l+1==r)return ;
int mid=(l+r)/2;
BulidTree(2*root,l,mid);
BulidTree(2*root+1,mid,r);
}
int serch(int *arr,int key)
{
int low,high,mid;
low=0;high=num-1;
while(low<=high)
{
mid=(low+high)/2;
if(key==arr[mid])return mid;
if(key>arr[mid])low=mid+1;
else high=mid-1;
}
return 0;
}
void Updata(int root)
{
if(tree[root].c>0)
{
tree[root].m=y[tree[root].r]-y[tree[root].l];
}
else if(tree[root].r-tree[root].l==1)tree[root].m=0;
else tree[root].m=tree[2*root].m+tree[2*root+1].m;
}
void insert(int root,int l,int r)
{
if(l<=tree[root].l&&tree[root].r<=r)
{
tree[root].c++;
Updata(root);
return;
}
if(tree[root].l+1==tree[root].r)return;
int mid=(tree[root].l+tree[root].r)/2;
if(l<mid)insert(2*root,l,r);
if(r>mid)insert(2*root+1,l,r);
Updata(root);
}
void Delet(int root,int l,int r)
{
if(l<=tree[root].l&&tree[root].r<=r)
{
tree[root].c--;
Updata(root);
return;
}
if(tree[root].l+1==tree[root].r)return;
int mid=(tree[root].l+tree[root].r)/2;
if(l<mid)Delet(2*root,l,r);
if(r>mid)Delet(2*root+1,l,r);
Updata(root);
}
int main()
{
int n;
while(scanf("%d",&n)&&n)
{
for(int i=0;i<n;i++)
{
int x1,y1,x2,y2,x3,y3,x4,y4;
scanf("%d%d%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
line[8*i].flag=true;
line[8*i].x=x1;
line[8*i].y1=y1;
line[8*i].y2=y2;
line[8*i+1].flag=false;
line[8*i+1].x=x3;
line[8*i+1].y1=y1;
line[8*i+1].y2=y2;
line[8*i+2].flag=true;
line[8*i+2].x=x3;
line[8*i+2].y1=y4;
line[8*i+2].y2=y2;
line[8*i+3].flag=false;
line[8*i+3].x=x4;
line[8*i+3].y1=y4;
line[8*i+3].y2=y2;
line[8*i+4].flag=true;
line[8*i+4].x=x3;
line[8*i+4].y1=y1;
line[8*i+4].y2=y3;
line[8*i+5].flag=false;
line[8*i+5].x=x4;
line[8*i+5].y1=y1;
line[8*i+5].y2=y3;
line[8*i+6].flag=true;
line[8*i+6].x=x4;
line[8*i+6].y1=y1;
line[8*i+6].y2=y2;
line[8*i+7].flag=false;
line[8*i+7].x=x2;
line[8*i+7].y1=y1;
line[8*i+7].y2=y2;
ty[4*i]=y1;
ty[4*i+1]=y2;
ty[4*i+2]=y3;
ty[4*i+3]=y4;
}
int num1=4*n;
int num2=8*n;
sort(line,line+num2,cmp);
sort(ty,ty+num1);
y[0]=ty[0];
for(int i=num=1;i<num1;i++)
{
if(ty[i]!=ty[i-1])
{
y[num++]=ty[i];
}
}
BulidTree(1,0,num-1);
__int64 area=0;
for(int i=0;i<num2;i++)
{
int l=serch(y,line[i].y1);
int r=serch(y,line[i].y2);
if(line[i].flag)insert(1,l,r);
else Delet(1,l,r);
area+=tree[1].m*(line[i+1].x-line[i].x);
}
printf("%I64d\n",area);
}
return 0;
}