• 扫描线


    将矩形分成上边和下边,用四元组((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];
    }
    
  • 相关阅读:
    用PHP写一个最简单的解释器Part4(写一个最简单的脚本语言)
    Java 引用传递
    Java 收集的代码 transient
    Java 继承 执行顺序
    Java 静态类 static
    Java 多态 虚方法
    Mongodb 安装
    入手Intel 750
    Intellij IDEA 创建控制台项目,断点调试快捷方式
    IntelliJ IDEA 的 Java 热部署插件 JRebel 安装及使用
  • 原文地址:https://www.cnblogs.com/lhm-/p/12229586.html
Copyright © 2020-2023  润新知