传送门1
传送门2
传送门3
思路:
有点纸张的做法
不会记录竖向边的个数
于是横着做一遍扫描线,竖着做一遍扫描线
好像还挺正确的……
但实际上可以通过当前扫到的横向边的类型来记录竖向边的个数
唉:-(……
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define M 5005
using namespace std;
int n;
int b[M<<1],cover[M<<3],lazy[M<<3];
struct node{
int up,down,data,tp;
}a[M<<1],c[M<<1];
bool cmp(node a,node b)
{
if (a.data==b.data) return a.tp>b.tp;
return a.data<b.data;
}
void update(int rt,int begin,int end,node x)
{
if (x.up<=begin&&end<=x.down)
{
lazy[rt]+=x.tp;
if (lazy[rt]) cover[rt]=b[end+1]-b[begin];
else if (begin==end) cover[rt]=0;
else cover[rt]=cover[rt<<1]+cover[rt<<1|1];
return;
}
int mid=begin+end>>1;
if (mid>=x.up) update(rt<<1,begin,mid,x);
if (mid<x.down) update(rt<<1|1,mid+1,end,x);
if (lazy[rt]) cover[rt]=b[end+1]-b[begin];
else cover[rt]=cover[rt<<1]+cover[rt<<1|1];
}
int get(int rt,int begin,int end,node x)
{
if (x.up<=begin&&end<=x.down) return cover[rt];
if (cover[rt]==b[end+1]-b[begin]) return b[min(end,x.down)+1]-b[max(begin,x.up)];
int mid=begin+end>>1,ans=0;
if (mid>=x.up) ans+=get(rt<<1,begin,mid,x);
if (mid<x.down) ans+=get(rt<<1|1,mid+1,end,x);
return ans;
}
main()
{
scanf("%d",&n);
int x,y,xx,yy;
for (int i=1;i<=n;++i)
scanf("%d%d%d%d",&x,&y,&xx,&yy),
b[i*2-1]=y,b[i*2]=yy,
a[i*2-1]=(node){y,yy,x,1},
a[i*2]=(node){y,yy,xx,-1},
c[i*2-1]=(node){x,xx,y,1},
c[i*2]=(node){x,xx,yy,-1};
sort(b+1,b+n*2+1);
b[0]=unique(b+1,b+n*2+1)-b-1;
for (int i=1;i<=n;++i)
a[i*2-1].up=a[i*2].up=lower_bound(b+1,b+b[0]+1,a[i*2-1].up)-b,
a[i*2-1].down=a[i*2].down=lower_bound(b+1,b+b[0]+1,a[i*2-1].down)-b-1;
sort(a+1,a+n*2+1,cmp);
int t=a[1].data,ans=0;
for (int i=1;i<=n<<1;++i)
{
if (a[i].tp==1)
ans+=b[a[i].down+1]-b[a[i].up]-get(1,1,b[0]-1,a[i]),
update(1,1,b[0]-1,a[i]);
else
update(1,1,b[0]-1,a[i]),
ans+=b[a[i].down+1]-b[a[i].up]-get(1,1,b[0]-1,a[i]);
t=a[i].data;
}
for (int i=1;i<=n;++i)
a[i*2-1]=c[i*2-1],
a[i*2]=c[i*2],
b[i*2-1]=a[i*2-1].up,
b[i*2]=a[i*2].down;
sort(b+1,b+n*2+1);
b[0]=unique(b+1,b+n*2+1)-b-1;
for (int i=1;i<=n;++i)
a[i*2-1].up=a[i*2].up=lower_bound(b+1,b+b[0]+1,a[i*2-1].up)-b,
a[i*2-1].down=a[i*2].down=lower_bound(b+1,b+b[0]+1,a[i*2-1].down)-b-1;
sort(a+1,a+n*2+1,cmp);
t=a[1].data;
for (int i=1;i<=n<<1;++i)
{
if (a[i].tp==1)
ans+=b[a[i].down+1]-b[a[i].up]-get(1,1,b[0]-1,a[i]),
update(1,1,b[0]-1,a[i]);
else
update(1,1,b[0]-1,a[i]),
ans+=b[a[i].down+1]-b[a[i].up]-get(1,1,b[0]-1,a[i]);
t=a[i].data;
}
printf("%d\n",ans);
}