• [P5490] 【模板】扫描线


    (n) 个矩形的面积并

    Solution

    将矩形转化为 (y_1) 位置的 + 修改 和 (y_2) 位置的 - 修改。然后按照 (+y) 顺序依次处理所有的修改,到达的一个新的位置就算一下上一段的总贡献。

    至于线段树,要么对 (x) 坐标离散化,要么动态开点。 我觉得后者比较快乐。

    注意这里的标记没有必要下传

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 5000005;
    
    struct event{
        int x1,x2,y,z;
        bool operator < (const event &b) {
            return y < b.y;
        }
    } e[N];
    
    int n,m,a[N],cnt[N],tag[N],ch[N][2],ind=1;
    
    void pushup(int p,int l,int r) {
        if(p==0) return;
        a[0]=0;
        if(cnt[p]) a[p]=r-l+1;
        else a[p]=a[ch[p][0]]+a[ch[p][1]];
    }
    
    void modify(int p,int l,int r,int ql,int qr,int c) {
        if(l>qr||r<ql) return;
        if(l>=ql&&r<=qr) {
            cnt[p]+=c;
            pushup(p,l,r);
        }
        else {
            if(ch[p][0]==0) ch[p][0]=++ind;
            if(ch[p][1]==0) ch[p][1]=++ind;
            modify(ch[p][0],l,(l+r)/2,ql,qr,c);
            modify(ch[p][1],(l+r)/2+1,r,ql,qr,c);
            pushup(p,l,r);
        }
    }
    
    signed main() {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {
            int x1,x2,y1,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            ++x1; ++x2;
            e[i*2-1]=(event){x1,x2,y1,1};
            e[i*2]=(event){x1,x2,y2,-1};
            m=max(m,x2);
        }
        sort(e+1,e+2*n+1);
        long long ans=0;
        for(int i=1;i<=2*n;i++) {
            if(e[i].y!=e[i-1].y) ans+=1ll*a[1]*(e[i].y-e[i-1].y);
            modify(1,1,m,e[i].x1+1,e[i].x2,e[i].z);
        }
        cout<<ans<<endl;
    }
    
  • 相关阅读:
    获取小程序码
    获取目标地与当前地距离
    小程序图片预览
    地图导航
    Jquery无缝滚动
    短信验证
    根据经纬度获取地址
    微信小程序中使用emoji表情
    小程序图片上传
    地球人类的牢笼
  • 原文地址:https://www.cnblogs.com/mollnn/p/12291186.html
Copyright © 2020-2023  润新知