将矩形分成上边和下边,用四元组((l,r,h,k))来表示一条边,其中(k=1)时,其为下边,(k=-1)时,其为下边,
扫描线从下往上扫,每次遇到一条上边或下边时,就停下来
用线段树维护,线段树的每个区间即为(x)轴上的区间,因数据过大,所以将(x)轴上的点离散化处理,那么就可以通过线段树的区间合并,来维护区间上线段的总长,线段的个数等信息
矩形面积
(code:)
struct line
{
int l,r,h,k;
}li[maxn];
bool cmp(const line &a,const line &b)
{
return a.h<b.h;
}
void pushup(int cur,int l,int r)
{
if(tag[cur]) val[cur]=x[r+1]-x[l];
else val[cur]=val[ls[cur]]+val[rs[cur]];
}
void modify(int L,int R,int l,int r,ll add,int &cur)
{
if(!cur) cur=++tree_cnt;
if(L<=l&&R>=r)
{
tag[cur]+=add;
pushup(cur,l,r);
return;
}
int mid=(l+r)>>1;
if(L<=mid) modify(L,R,l,mid,add,ls[cur]);
if(R>mid) modify(L,R,mid+1,r,add,rs[cur]);
pushup(cur,l,r);
}
......
for(int i=1;i<=n;++i)
{
read(ax),read(ay),read(bx),read(by);
x[i<<1]=ax,x[(i<<1)-1]=bx;
li[i<<1]=(line){ax,bx,ay,1};
li[(i<<1)-1]=(line){ax,bx,by,-1};
}
sort(x+1,x+2*n+1);
sort(li+1,li+2*n+1,cmp);
tot=unique(x+1,x+2*n+1)-x-2;
for(int i=1;i<=2*n;++i)
{
int l=lower_bound(x+1,x+tot+1,li[i].l)-x;
int r=lower_bound(x+1,x+tot+1,li[i].r)-x-1;
ans+=val[root]*(li[i].h-li[i-1].h);
modify(l,r,1,tot,li[i].k,root);
}
矩形周长
(code:)
struct line
{
int l,r,h,k;
}li[maxn];
bool cmp(const line &a,const line &b)
{
if(a.h==b.h) return a.k>b.k;
return a.h<b.h;
}
void pushup(int cur,int l,int r)
{
if(tag[cur])
{
num[cur]=1;
val[cur]=x[r+1]-x[l];
fl[cur]=fr[cur]=true;
return;
}
if(l==r)
{
val[cur]=num[cur]=fl[cur]=fr[cur]=0;
return;
}
num[cur]=num[ls[cur]]+num[rs[cur]];
val[cur]=val[ls[cur]]+val[rs[cur]];
if(fr[ls[cur]]&&fl[rs[cur]]) num[cur]--;
fl[cur]=fl[ls[cur]],fr[cur]=fr[rs[cur]];
}
void modify(int L,int R,int l,int r,ll add,int &cur)
{
if(!cur) cur=++tree_cnt;
if(L<=l&&R>=r)
{
tag[cur]+=add;
pushup(cur,l,r);
return;
}
int mid=(l+r)>>1;
if(L<=mid) modify(L,R,l,mid,add,ls[cur]);
if(R>mid) modify(L,R,mid+1,r,add,rs[cur]);
pushup(cur,l,r);
}
......
for(int i=1;i<=n;++i)
{
read(ax),read(ay),read(bx),read(by);
x[i<<1]=ax,x[(i<<1)-1]=bx;
li[i<<1]=(line){ax,bx,ay,1};
li[(i<<1)-1]=(line){ax,bx,by,-1};
}
sort(x+1,x+2*n+1);
sort(li+1,li+2*n+1,cmp);
tot=unique(x+1,x+2*n+1)-x-2;
for(int i=1;i<=2*n;++i)
{
int l=lower_bound(x+1,x+tot+1,li[i].l)-x;
int r=lower_bound(x+1,x+tot+1,li[i].r)-x-1;
modify(l,r,1,tot,li[i].k,root);
ans+=abs(val[root]-las)+2*num[root]*(li[i+1].h-li[i].h);
las=val[root];
}