zoukankan      html  css  js  c++  java
  • 学习笔记 扫描线(面积并)

    模板题:https://www.luogu.org/problem/P5490

    这个是用于求面积并的扫描线。

    显然只有矩形的两边会使答案发生变化。

    所以对每一个边做出一个四元组(x,yl,yh,1/-1)

    x就是x坐标 yl,yh是这条线的纵坐标,1为左端点,-1为右端点。

     然后就可以用线段树模拟线去扫描。

    在线段树里维护两个信息cnt,len。

    cnt表示有多少个点覆盖,len表示覆盖的长度。

    这样的话就可以ans+=(len(i)*x差)。

    代码如下:

    #include<bits/stdc++.h>
    #define int long long
    #define ll long long
    using namespace std;
    const int maxn=1e6+10;
    int n,tot,b[maxn<<1],val[maxn<<1],maxx;
    struct n1{
        int x,yl,yh,fl;
    }e[maxn<<1];
    struct node{
        ll len,cnt;
        #define len(x) t[x].len
        #define cnt(x) t[x].cnt
    }t[maxn<<1];
    inline bool cmp1(n1 x,n1 y){
        return x.x==y.x ? x.fl<y.fl : x.x<y.x;
    }
    inline void pushup(int p,int l,int r){
        if(l==r&&r==maxx) return;
        if(cnt(p)) len(p)=val[r+1]-val[l];
        else len(p)=len(p<<1)+len(p<<1|1);
    }
    inline void add(int p,int l,int r,int x,int y,int d){
        if(x<=l&&r<=y){
            cnt(p)+=d;
            pushup(p,l,r);
            return;
        }
        int mid=(l+r)>>1;
        if(x<=mid) add(p<<1,l,mid,x,y,d);
        if(y>mid) add(p<<1|1,mid+1,r,x,y,d);
        pushup(p,l,r);
    }
    signed main()
    {
        scanf("%lld",&n);
        for(int i=1;i<=n;i++){
            int x,y,xx,yy;
            scanf("%lld%lld%lld%lld",&x,&y,&xx,&yy);
            e[++tot].x=x;b[tot]=y;
            e[tot].yl=y;e[tot].yh=yy;e[tot].fl=1;
    
            e[++tot].x=xx;b[tot]=yy;
            e[tot].yl=y;e[tot].yh=yy;e[tot].fl=-1;
        }
        sort(b+1,b+1+tot);
        tot=unique(b+1,b+1+tot)-b-1;
        for(int i=1;i<=2*n;i++){
            int h1=lower_bound(b+1,b+1+tot,e[i].yh)-b;
            int h2=lower_bound(b+1,b+1+tot,e[i].yl)-b;
            val[h1]=e[i].yh;val[h2]=e[i].yl;
            e[i].yh=h1;e[i].yl=h2;
            maxx=max(maxx,h1);
        }
        sort(e+1,e+1+2*n,cmp1);
        ll ans=0;
        for(int i=1;i<=2*n;i++){
            add(1,1,2*n,e[i].yl,e[i].yh-1,e[i].fl);
            ans+=len(1)*(e[i+1].x-e[i].x);
        }
        printf("%lld
    ",ans);
        //system("pause");
        return 0;
    }
  • 相关阅读:
    docker的基本操作
    docker和虚拟化技术的区别
    项目命名规则
    Javascript IE 内存释放
    关于ie的内存泄漏与javascript内存释放
    Java遍历HashMap并修改(remove)
    java 中类的加载顺序
    java类的加载以及初始化顺序 .
    JavaScript也谈内存优化
    JavaScript 的垃圾回收与内存泄露
  • 原文地址:https://www.cnblogs.com/ChrisKKK/p/11491902.html
Copyright © 2011-2022 走看看