Time Limit: 2000MS | Memory Limit: 10000K | |
Total Submissions: 8215 | Accepted: 4347 |
Description
Write a program to calculate the perimeter. An example with 7 rectangles is shown in Figure 1.
The corresponding boundary is the whole set of line segments drawn in Figure 2.
The vertices of all rectangles have integer coordinates.
Input
0 <= number of rectangles < 5000
All coordinates are in the range [-10000,10000] and any existing rectangle has a positive area.
Output
Sample Input
7 -15 0 5 10 -5 8 20 25 15 -4 24 14 0 -6 16 4 2 15 10 22 30 10 36 20 34 0 40 16
Sample Output
228
Source
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define N 10003
#define lson l,m,k<<1
#define rson m,r,k<<1|1
using namespace std;
struct segment
{
int len,cover;//研究发现每次更新后树中的覆盖区间有变化值,可以累加起来、就可以得周长
};
struct line1
{
int x,y1,y2;
int flag;
bool operator<(const line1 &L) const
{
if(x==L.x)//开始没这个、遇到 2 (0,0)(1,1) (1,0) (2 1)我的结果就错了,不过提交时居然A了,
return flag>L.flag;
return x<L.x;
}
};
struct line2
{
int y,x1,x2;
int flag;
bool operator<(const line2 &L) const
{
if(y==L.y)
return flag>L.flag;
return y<L.y;
}
};
segment st[N<<2];
line1 L1[N];
line2 L2[N];
int rcx[N],rcy[N];
void up1(int &k,int &l,int &r)
{
if(st[k].cover)
st[k].len=rcy[r]-rcy[l];
else if(l+1==r)
st[k].len=0;
else
st[k].len=st[k<<1].len+st[k<<1|1].len;
}
void up2(int &k,int &l,int &r)
{
if(st[k].cover)
st[k].len=rcx[r]-rcx[l];
else if(l+1==r)
st[k].len=0;
else
st[k].len=st[k<<1].len+st[k<<1|1].len;
}
void build(int l,int r,int k)
{
st[k].cover=st[k].len=0;
if(l+1==r)
return ;
int m=(l+r)>>1;
build(lson);
build(rson);
}
int flag;
void update1(int &y1,int &y2,int l,int r,int k)
{
if(y1<=rcy[l]&&rcy[r]<=y2)
{
st[k].cover+=flag;
up1(k,l,r);
return ;
}
int m=(l+r)>>1;
if(y1<rcy[m]) update1(y1,y2,lson);
if(y2>rcy[m]) update1(y1,y2,rson);
up1(k,l,r);
}
void update2(int &x1,int &x2,int l,int r,int k)
{
if(x1<=rcx[l]&&rcx[r]<=x2)
{
st[k].cover+=flag;
up2(k,l,r);
return ;
}
int m=(l+r)>>1;
if(x1<rcx[m]) update2(x1,x2,lson);
if(x2>rcx[m]) update2(x1,x2,rson);
up2(k,l,r);
}
int main()
{
int n,nl,pl,len;
int i,j,k;
int x1,x2,y1,y2;
while(scanf("%d",&n)!=EOF)
{
for(j=i=0;i<n;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
L1[j].x=x1;L1[j].y1=y1;L1[j].y2=y2;
L2[j].y=y1;L2[j].x1=x1;L2[j].x2=x2;
L1[j].flag=L2[j].flag=1;
rcx[j]=x1;rcy[j]=y1; j++;
rcx[j]=x2;rcy[j]=y2;
L1[j].x=x2;L1[j].y1=y1;L1[j].y2=y2;
L2[j].y=y2;L2[j].x1=x1;L2[j].x2=x2;
L1[j].flag=L2[j].flag=-1; j++;
}
sort(L1,L1+j);//一下的代码冗长呀、呵呵
sort(rcy,rcy+j);
for(k=0,i=1;i<j;i++)
if(rcy[i]!=rcy[k])
rcy[++k]=rcy[i];
build(0,k,1);
len=0;
for(i=0;i<j;i++)
{
pl=st[1].len;
flag=L1[i].flag;
update1(L1[i].y1,L1[i].y2,0,k,1);
nl=st[1].len;
len+=pl>nl?pl-nl:nl-pl;
}
sort(L2,L2+j);
sort(rcx,rcx+j);
for(k=0,i=1;i<j;i++)
if(rcx[i]!=rcx[k])
rcx[++k]=rcx[i];
build(0,k,1);
//len=0;
for(i=0;i<j;i++)
{
pl=st[1].len;
flag=L2[i].flag;
update2(L2[i].x1,L2[i].x2,0,k,1);
nl=st[1].len;
len+=pl>nl?pl-nl:nl-pl;
}
printf("%d\n",len);
}
return 0;
}