思路:扫两遍,分别求横竖边
#include<bits/stdc++.h>
#define int long long
#define maxn 4000005
using namespace std;
int tongx[maxn],totx,n,totline,tongy[maxn],toty,maxx;
unsigned long long ans;bool Merge[maxn<<2];
struct matrix{int l1,r1,l2,r2;}a[maxn];
struct seg{int l,r;unsigned long long len;int tag;}tree[maxn<<2];
struct line{int l,r,tag,y;}tongline[maxn<<2];
inline bool cmp(line aaa,line bbb){return aaa.y<bbb.y;}
void build(int id,int l,int r){
maxx=max(maxx,id);
tree[id]=(seg){l,r,0,0};
if(l==r)return;
int mid=l+r>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
}
void pushup(int rt,int op){
int l=tree[rt].l,r=tree[rt].r;
if(tree[rt].tag)tree[rt].len=(op==1)?tongx[r+1]-tongx[l]:tongy[r+1]-tongy[l];
else tree[rt].len=tree[rt<<1].len+tree[rt<<1|1].len;
return;
}
void modify(int id,int l,int r,int tag,int op){
if(tree[id].r<l||tree[id].l>r)return;
if(l<=tree[id].l&&tree[id].r<=r){
tree[id].tag+=tag;
pushup(id,op);
return;
}
modify(id<<1,l,r,tag,op);
modify(id<<1|1,l,r,tag,op);
pushup(id,op);
return;
}
bool chk(line aaa,line bbb){
if(aaa.y!=bbb.y)return 0;
if(aaa.l>bbb.r||aaa.r<bbb.l)return 0;
return 1;
}
signed main(){
cin>>n;
for(int i(1);i<=n;++i)cin>>a[i].l1>>a[i].l2>>a[i].r1>>a[i].r2;
for(int i(1);i<=n;++i){
tongx[++totx]=a[i].l1;
tongx[++totx]=a[i].r1;
tongy[++toty]=a[i].l2;
tongy[++toty]=a[i].r2;
}
sort(tongx+1,tongx+1+totx);totx=unique(tongx+1,tongx+1+totx)-(tongx+1);
sort(tongy+1,tongy+1+toty);toty=unique(tongy+1,tongy+1+toty)-(tongy+1);
for(int i(1);i<=n;++i){
a[i].l1=lower_bound(tongx+1,tongx+1+totx,a[i].l1)-(tongx);
a[i].r1=lower_bound(tongx+1,tongx+1+totx,a[i].r1)-(tongx);
a[i].l2=lower_bound(tongy+1,tongy+1+toty,a[i].l2)-(tongy);
a[i].r2=lower_bound(tongy+1,tongy+1+toty,a[i].r2)-(tongy);
tongline[++totline]={a[i].l1,a[i].r1,1,a[i].l2};
tongline[++totline]={a[i].l1,a[i].r1,-1,a[i].r2};
}
sort(tongline+1,tongline+1+totline,cmp);build(1,1,totx-1);
int resans=0;
for(int i=1;i<=totline;++i){
if(Merge[i])continue;
while(i+1<=totline&&chk(tongline[i],tongline[i+1])){
tongline[i+1].l=min(tongline[i+1].l,tongline[i].l);
tongline[i+1].r=max(tongline[i+1].r,tongline[i].r);
Merge[i]=1;i++;
}
}
for(int i=1;i<=totline;++i){
if(Merge[i])continue;
modify(1,tongline[i].l,tongline[i].r-1,tongline[i].tag,1);
int nowans=tree[1].len;
ans+=abs(nowans-resans);resans=nowans;
}ans+=tree[1].len;
totline=0;
for(int i(1);i<=n;++i){
tongline[++totline]={a[i].l2,a[i].r2,1,a[i].l1};
tongline[++totline]={a[i].l2,a[i].r2,-1,a[i].r1};
}
for(int i=1;i<=maxx;++i)tree[i].l=tree[i].r=tree[i].len=tree[i].tag=0;
sort(tongline+1,tongline+1+totline,cmp);build(1,1,toty-1);resans=0;
memset(Merge,0,sizeof Merge);
for(int i=1;i<=totline;++i){
if(Merge[i])continue;
while(i+1<=totline&&chk(tongline[i],tongline[i+1])){
tongline[i+1].l=min(tongline[i+1].l,tongline[i].l);
tongline[i+1].r=max(tongline[i+1].r,tongline[i].r);
Merge[i]=1;i++;
}
}
for(int i=1;i<=totline;++i){
if(Merge[i])continue;
modify(1,tongline[i].l,tongline[i].r-1,tongline[i].tag,0);
int nowans=tree[1].len;
ans+=abs(nowans-resans);resans=nowans;
}ans+=tree[1].len;
cout<<ans;
return 0;
}