题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1828
题意:矩形周长并。
思路:节点保存的是一段,这一段的长度以及横向线段的个数。
struct node
{
int L,R,len,sum,segCount,coverNum;
int LcoverNum,RcoverNum;
};
struct line
{
int x,y1,y2,flag;
line(){}
line(int _x,int _y1,int _y2,int _flag)
{
x=_x;
y1=_y1;
y2=_y2;
flag=_flag;
}
};
node a[N*3];
line L[N];
int y[N],n,yNum,LNum;
struct pol
{
int x1,y1,x2,y2;
void get()
{
RD(x1,y1);
RD(x2,y2);
if(x1>x2) swap(x1,x2);
if(y1>y2) swap(y1,y2);
}
};
pol p[N];
int cmp(line a,line b)
{
return a.x<b.x;
}
int find(int x)
{
int low=0,high=yNum-1,mid;
while(low<=high)
{
mid=(low+high)>>1;
if(y[mid]==x) return mid;
if(y[mid]>x) high=mid-1;
else low=mid+1;
}
}
void build(int t,int L,int R)
{
a[t].L=L;
a[t].R=R;
a[t].coverNum=0;
a[t].segCount=0;
a[t].sum=0;
a[t].LcoverNum=a[t].RcoverNum=0;
a[t].len=y[R]-y[L];
if(L+1<R)
{
int mid=(L+R)>>1;
build(t*2,L,mid);
build(t*2+1,mid,R);
}
}
void up(int t)
{
if(a[t].coverNum>0) a[t].sum=a[t].len;
else if(a[t].L+1<a[t].R) a[t].sum=a[t*2].sum+a[t*2+1].sum;
else a[t].sum=0;
if(a[t].coverNum>0)
{
a[t].LcoverNum=a[t].RcoverNum=1;
a[t].segCount=1;
}
else if(a[t].L+1<a[t].R)
{
a[t].LcoverNum=a[t*2].LcoverNum;
a[t].RcoverNum=a[t*2+1].RcoverNum;
a[t].segCount=a[t*2].segCount+a[t*2+1].segCount-a[t*2].RcoverNum*a[t*2+1].LcoverNum;
}
else
{
a[t].LcoverNum=a[t].RcoverNum=0;
a[t].segCount=0;
}
}
void insert(int t,int L,int R,int det)
{
int mid=(a[t].L+a[t].R)>>1;
if(a[t].L==L&&a[t].R==R) a[t].coverNum+=det;
else if(R<=mid) insert(t*2,L,R,det);
else if(L>=mid) insert(t*2+1,L,R,det);
else
{
insert(t*2,L,mid,det);
insert(t*2+1,mid,R,det);
}
up(t);
}
int cal(pol p[],int n)
{
LNum=yNum=0;
int i,x1,y1,x2,y2;
FOR0(i,n)
{
x1=p[i].x1; y1=p[i].y1;
x2=p[i].x2; y2=p[i].y2;
L[LNum++]=line(x1,y1,y2,1);
L[LNum++]=line(x2,y1,y2,-1);
y[yNum++]=y1;
y[yNum++]=y2;
}
sort(y,y+yNum);
sort(L,L+LNum,cmp);
yNum=unique(y,y+yNum)-y;
build(1,0,yNum-1);
int ans=0,preLen=0;
for(i=0;i+1<LNum;i++)
{
x1=find(L[i].y1);
x2=find(L[i].y2);
insert(1,x1,x2,L[i].flag);
ans+=2*a[1].segCount*(L[i+1].x-L[i].x);
ans+=abs(a[1].sum-preLen);
preLen=a[1].sum;
}
insert(1,find(L[i].y1),find(L[i].y2),-1);
ans+=abs(a[1].sum-preLen);
return ans;
}
int main()
{
while(scanf("%d",&n)!=-1)
{
int i;
FOR0(i,n) p[i].get();
PR(cal(p,n));
}
return 0;
}