一道扫描线好题,由于是周长,因此不连续的竖段,对横边会产生贡献。
注意:优先加入左边界。

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#define gc getchar()
using namespace std;
const int N=1e4+10;
inline void read(int &x)
{
    x=0;char c=gc;int f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc;}
    while(c>='0'&&c<='9'){x=x*10+(c^48);c=gc;}
    x*=f;
}
void qw(int x)
{
    if(x<0)putchar('-'),x=-x;
    if(x/10)qw(x/10);
    putchar(x%10+48);
}
struct node{int x,y1,y2,c;bool operator <(const node a)const{return x==a.x?c>a.c:x<a.x;}}a[N];
struct Seg{bool ls,rs;int c,num,len;}t[N<<2];
void update(int p,int l,int r)
{
    if(t[p].c)
    {
        t[p].ls=t[p].rs=1;
        t[p].num=2;
        t[p].len=r-l+1;
    }
    else if(l==r)t[p].ls=t[p].rs=0,t[p].num=t[p].len=0;
    else
    {
        t[p].ls=t[p<<1].ls;
        t[p].rs=t[p<<1|1].rs;
        t[p].len=t[p<<1].len+t[p<<1|1].len;
        t[p].num=t[p<<1].num+t[p<<1|1].num;
        if(t[p<<1].rs&&t[p<<1|1].ls)t[p].num-=2;
    }
}
void change(int p,int l,int r,int ql,int qr,int k)
{
    if(ql<=l&&qr>=r){t[p].c+=k;update(p,l,r);return ;}
    int mid=l+r>>1;
    if(ql<=mid)change(p<<1,l,mid,ql,qr,k);
    if(qr>mid)change(p<<1|1,mid+1,r,ql,qr,k);
    update(p,l,r);
}
int main()
{
    int n;read(n);int l=10001,r=-10001;
    for(int i=1;i<=n;i++)
    {
        int k=i<<1;
        int x1,y1,x2,y2;read(x1),read(y1),read(x2),read(y2);
        a[k-1]=(node){x1,y1,y2,1},a[k]=(node){x2,y1,y2,-1};
        l=min(y1,l),r=max(y2,r);
    }
    n<<=1;
    sort(a+1,a+n+1);
    int last=0,ans=0;
    for(int i=1;i<=n;i++)
    {
        if(i!=1)ans+=t[1].num*(a[i].x-a[i-1].x);
        change(1,l,r,a[i].y1,a[i].y2-1,a[i].c);
        ans+=abs(t[1].len-last);
        last=t[1].len;
    }
    qw(ans);puts("");
    return 0;
}