
 /**//*
/**//*
 Author:miyou
Author:miyou
 PROG:the perimeter of many rectangles
PROG:the perimeter of many rectangles
 LANG:C++
LANG:C++
 */
*/
 #include<iostream>
#include<iostream>
 #include<vector>
#include<vector>
 #include<algorithm>
#include<algorithm>
 using namespace std;
using namespace std;
 #define MAXN 1000000
#define MAXN 1000000
 const __int64 mininf=1000000;
const __int64 mininf=1000000;
 const __int64 maxinf=-1000000;
const __int64 maxinf=-1000000;
 struct Line
struct Line


 {
{
 __int64 count,len;//count 记录线段覆盖次数,len 该段线段长度
    __int64 count,len;//count 记录线段覆盖次数,len 该段线段长度
 __int64 l,r;//线段左右两端点
    __int64 l,r;//线段左右两端点
 int lbc,rbc;//线段左右两端点被覆盖的次数,0表示未被覆盖
    int lbc,rbc;//线段左右两端点被覆盖的次数,0表示未被覆盖
 __int64 nseg;//该线段中连续线段个数.
    __int64 nseg;//该线段中连续线段个数.
 };
};
 struct node
struct node


 {
{
 __int64 x,down,up;//扫描线,down 线的下端点,up 线的上端点,x扫描线的x位置
    __int64 x,down,up;//扫描线,down 线的下端点,up 线的上端点,x扫描线的x位置
 bool flag;//表示是矩形的左边线还是右边线
    bool flag;//表示是矩形的左边线还是右边线
 node(__int64 tx,__int64 td,__int64 tu,bool tf):x(tx),down(td),up(tu),flag(tf)
    node(__int64 tx,__int64 td,__int64 tu,bool tf):x(tx),down(td),up(tu),flag(tf)

 
     {
{
 }
    }
 };
};
 __int64 miny,maxy;
__int64 miny,maxy;
 vector< node > vec;
vector< node > vec;
 Line Ltree[MAXN];
Line Ltree[MAXN];
 bool operator< (const node& a,const node& b)
bool operator< (const node& a,const node& b)


 {
{
 return a.x<b.x;
    return a.x<b.x;
 }
}
 void build(__int64 l,__int64 r,int step)
void build(__int64 l,__int64 r,int step)


 {
{
 Ltree[step].count=0;Ltree[step].len=0;
    Ltree[step].count=0;Ltree[step].len=0;
 Ltree[step].lbc=false;Ltree[step].rbc=false;
    Ltree[step].lbc=false;Ltree[step].rbc=false;
 Ltree[step].nseg=0;
    Ltree[step].nseg=0;
 Ltree[step].r=r;Ltree[step].l=l;
    Ltree[step].r=r;Ltree[step].l=l;
 if(r-l>1)
    if(r-l>1)

 
     {
{
 build(l,(l+r)/2,2*step);
        build(l,(l+r)/2,2*step);
 build((l+r)/2,r,2*step+1);
        build((l+r)/2,r,2*step+1);
 }
    }
 }
}
 void update(int step)
void update(int step)


 {
{
 if(Ltree[step].count>0)
    if(Ltree[step].count>0)

 
     {
{
 Ltree[step].len=Ltree[step].r-Ltree[step].l;
        Ltree[step].len=Ltree[step].r-Ltree[step].l;
 Ltree[step].nseg=1;
        Ltree[step].nseg=1;
 }
    }
 else
    else
 if(Ltree[step].r-Ltree[step].l>1)
        if(Ltree[step].r-Ltree[step].l>1)

 
         {
{
 Ltree[step].len=Ltree[2*step].len+Ltree[2*step+1].len;
            Ltree[step].len=Ltree[2*step].len+Ltree[2*step+1].len;
 Ltree[step].nseg=Ltree[2*step].nseg+Ltree[2*step+1].nseg;
            Ltree[step].nseg=Ltree[2*step].nseg+Ltree[2*step+1].nseg;
 if(Ltree[step].nseg&&Ltree[2*step].rbc&&Ltree[2*step+1].lbc)
            if(Ltree[step].nseg&&Ltree[2*step].rbc&&Ltree[2*step+1].lbc)
 Ltree[step].nseg--;
                Ltree[step].nseg--;
 }
        }
 else
        else

 
         {
{
 Ltree[step].len=0;
            Ltree[step].len=0;
 Ltree[step].nseg=0;
            Ltree[step].nseg=0;
 }
        }
 }
}
 void insert(__int64 l,__int64 r,int step)
void insert(__int64 l,__int64 r,int step)


 {
{
 if(Ltree[step].l==l) Ltree[step].lbc++;
    if(Ltree[step].l==l) Ltree[step].lbc++;
 if(Ltree[step].r==r) Ltree[step].rbc++;
    if(Ltree[step].r==r) Ltree[step].rbc++;
 if(l==Ltree[step].l&&Ltree[step].r==r)
    if(l==Ltree[step].l&&Ltree[step].r==r)
 Ltree[step].count++;
        Ltree[step].count++;
 else
    else

 
     {
{
 __int64 mid=(Ltree[step].l+Ltree[step].r)/2;
        __int64 mid=(Ltree[step].l+Ltree[step].r)/2;
 if(r<=mid)
        if(r<=mid)
 insert(l,r,2*step);
            insert(l,r,2*step);
 else
        else 
 if(l>=mid)
            if(l>=mid)
 insert(l,r,2*step+1);
                insert(l,r,2*step+1);
 else
            else

 
             {
{
 insert(l,mid,2*step);
                insert(l,mid,2*step);
 insert(mid,r,2*step+1);
                insert(mid,r,2*step+1);
 }
            }
 }
    }
 update(step);
    update(step);
 }
}
 void del(__int64 l,__int64 r,int step)
void del(__int64 l,__int64 r,int step)


 {
{
 if(Ltree[step].l==l) Ltree[step].lbc--;
    if(Ltree[step].l==l) Ltree[step].lbc--;
 if(Ltree[step].r==r) Ltree[step].rbc--;
    if(Ltree[step].r==r) Ltree[step].rbc--;
 if(l==Ltree[step].l&&Ltree[step].r==r)
    if(l==Ltree[step].l&&Ltree[step].r==r)
 Ltree[step].count--;
        Ltree[step].count--;
 else
    else

 
     {
{
 __int64 mid=(Ltree[step].l+Ltree[step].r)/2;
        __int64 mid=(Ltree[step].l+Ltree[step].r)/2;
 if(r<=mid)
        if(r<=mid)
 del(l,r,2*step);
            del(l,r,2*step);
 else
        else 
 if(l>=mid)
            if(l>=mid)
 del(l,r,2*step+1);
                del(l,r,2*step+1);
 else
            else

 
             {
{
 del(l,mid,2*step);
                del(l,mid,2*step);
 del(mid,r,2*step+1);
                del(mid,r,2*step+1);
 }
            }
 }
    }
 update(step);
    update(step);
 }
}

 int main()
int main()


 {
{
 int n;
    int n;
 __int64 x1,x2,y1,y2;
    __int64 x1,x2,y1,y2;
 while(scanf("%d",&n)==1)
    while(scanf("%d",&n)==1)

 
     {
{
 miny=mininf;
        miny=mininf;
 maxy=maxinf;
        maxy=maxinf;
 for(int i=0;i<n;i++)
        for(int i=0;i<n;i++)

 
         {
{
 scanf("%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2);
            scanf("%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2);
 vec.push_back(node(x1,y1,y2,true));
            vec.push_back(node(x1,y1,y2,true));
 vec.push_back(node(x2,y1,y2,false));
            vec.push_back(node(x2,y1,y2,false));
 miny=min(miny,y1);
            miny=min(miny,y1);
 maxy=max(maxy,y2);
            maxy=max(maxy,y2);
 }
        }
 sort(vec.begin(),vec.end());
        sort(vec.begin(),vec.end());
 //cout<<miny<<" "<<maxy<<endl;
        //cout<<miny<<" "<<maxy<<endl;
 build(miny,maxy,1);
        build(miny,maxy,1);
 __int64 peri=0;
        __int64 peri=0;
 int m=vec.size();
        int m=vec.size();
 __int64 lastlen=0,lastseg=0;
        __int64 lastlen=0,lastseg=0;
 for(int i=0;i<m;i++)
        for(int i=0;i<m;i++)

 
         {
{
 if(vec[i].flag)
            if(vec[i].flag)
 insert(vec[i].down,vec[i].up,1);
                insert(vec[i].down,vec[i].up,1);
 else
            else
 del(vec[i].down,vec[i].up,1);
                del(vec[i].down,vec[i].up,1);
 peri+=abs(Ltree[1].len-lastlen);
            peri+=abs(Ltree[1].len-lastlen);
 //cout<<"len:"<<Ltree[1].len<<endl;
            //cout<<"len:"<<Ltree[1].len<<endl;
 lastlen=Ltree[1].len;
            lastlen=Ltree[1].len;
 if(i)
            if(i)
 peri+=2*(vec[i].x-vec[i-1].x)*lastseg;
                peri+=2*(vec[i].x-vec[i-1].x)*lastseg;
 lastseg=Ltree[1].nseg;
            lastseg=Ltree[1].nseg;
 //cout<<"seg:"<<Ltree[1].nseg<<endl;
            //cout<<"seg:"<<Ltree[1].nseg<<endl;
 }
        }
 printf("%I64d\n",peri);
        printf("%I64d\n",peri);
 }
    }
 return 0;
    return 0;
 }
}



posted on 2009-05-03 21:02 
米游 阅读(799) 
评论(0)  编辑 收藏 引用  所属分类: 
ACM