/*
hdu 3265 Posters 线段树+扫描线
用一些中间有矩形洞的矩形海报去糊窗户
文被覆盖的面积
线段树+扫描线
可以简单看一下扫面线,这里只是简单应用(因为边只有水平、垂直两种,所以不用y=y+1地扫,也不用在求交点)
在水平方向上做线段树,进行扫描
每个矩形记录两条边,底边给这段涂上颜色,顶边把颜色去掉
对于大数据,c++的容器的速度还真不敢恭维,以后还是用c吧
改c的时候读x3的时候忘了&
其中还出现几次 Runtime Error(STACK_OVERFLOW) 是因为maxx写成了5555
*/
#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;
const int maxx=55555;
struct node
{
__int64 sum,color;
}tree[maxx<<3];
struct seg
{
int x1,x2,y,color;
seg(int a,int b,int c,int d):x1(a),x2(b),y(c),color(d){}
bool operator < (const seg &t)const{
return y < t.y;
}
};
void pushUp(int no,int l,int r)
{
if(tree[no].color) tree[no].sum=r-l+1;
else if(l==r) tree[no].sum=0;
else tree[no].sum=tree[no<<1].sum+tree[no<<1|1].sum;
}
void update(int x1,int x2,int color,int l,int r,int no)
{
if(x1<=l&&r<=x2)//整个区间涂上颜色或去掉颜色
{
tree[no].color+=color;
pushUp(no,l,r);//更新所涂长度
return;
}
int m=(l+r)>>1;//左右分别
if(x1<=m) update(x1,x2,color,l,m,no<<1);//注意等号
if(x2>m) update(x1,x2,color,m+1,r,no<<1|1);
pushUp(no,l,r);
}
int main()
{
int n,x1,x2,x3,x4,y1,y2,y3,y4,i;
while(cin>>n,n)
{
vector<seg> v;
for(i=1;i<=n;++i)
{
cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4;
if(x1<x3)//拆成四个矩形
{
v.push_back(seg(x1,x3,y1,1));//底边给这段涂上颜色,
v.push_back(seg(x1,x3,y2,-1));//顶边把颜色去掉
}
if(x4<x2)
{
v.push_back(seg(x4,x2,y1,1));
v.push_back(seg(x4,x2,y2,-1));
}
if(y1<y3)
{
v.push_back(seg(x3,x4,y1,1));
v.push_back(seg(x3,x4,y3,-1));
}
if(y4<y2)
{
v.push_back(seg(x3,x4,y4,1));
v.push_back(seg(x3,x4,y2,-1));
}
}
sort(v.begin(),v.end());//从小到大排序,从小的开始扫描
memset(tree,0,sizeof(tree));
__int64 ret=0;
int end=v.size();
for(i=0;i<end-1;++i)
{
if(v[i].x2>v[i].x1)
update(v[i].x1,v[i].x2-1,v[i].color,0,maxx,1);//对每条边 经行 涂颜色或去颜色 注意第二个参数-1 左闭右开,防止一个点算两次
ret+=tree[1].sum*(v[i+1].y-v[i].y);//根据所涂长度 及 高度差 算面积
}
printf("%I64d\n",ret);
}
return 0;
}