码迷,mamicode.com
首页 > 其他好文 > 详细

扫描线

时间:2020-01-22 22:08:00      阅读:83      评论:0      收藏:0      [点我收藏+]

标签:hup   push   add   mod   shu   bool   code   return   odi   

将矩形分成上边和下边,用四元组\((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];
}

扫描线

标签:hup   push   add   mod   shu   bool   code   return   odi   

原文地址:https://www.cnblogs.com/lhm-/p/12229586.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!