luogu_P5490 【模板】扫描线

离散化+缩水版线段树+扫描线思想

太毒瘤了

#include<iostream>
#include<cstdio>

#define ri register int
#define u long long
#define NN 200005

namespace xds {

    u b[NN<<2];

    struct node {
        u n,l,r,adn;
        u v;
    } a[NN<<3];

    void build(const u &rt,const u &l,const u &r) {
        a[rt].l=l,a[rt].r=r,a[rt].n=a[rt].adn=0,a[rt].v=0.0;
        if(l==r) return;
        u mid(l+r>>1);
        build(rt<<1,l,mid),build(rt<<1|1,mid+1,r);
    }

    void pushup(const u &rt) {
        if(a[rt].n>0) a[rt].v=b[a[rt].r+1]-b[a[rt].l];
        else if(a[rt].l==a[rt].r) a[rt].v=0;
        else a[rt].v=a[rt<<1].v+a[rt<<1|1].v;
    }

    void update(const u &rt,const u &l,const u &r,const u &k) {
        if(a[rt].l>=l&&a[rt].r<=r) {
            a[rt].n+=k;
            pushup(rt);
            return;
        }
        u _x(rt<<1),_y(rt<<1|1);
        if(a[_x].r>=l) update(_x,l,r,k);
        if(a[_y].l<=r) update(_y,l,r,k);
        pushup(rt);
    }

}

#include<algorithm>

namespace mainstay {

    u N;

    using xds::b;

    u n2;

    using std::cin;

    struct node {
        u k;
        u x,y1,y2;
    } c[NN<<2];

    u n1;

    inline bool cmp(const node &x,const node &y) {
        return x.x<y.x;
    }

    u cas;

    inline void solve() {
        u s(1);
        while(s--) {
            ++cas;
            cin>>N;
            if(!N) return;
            xds::build(1,1,N*4);
            for(ri i(1); i<=N; ++i) {
                u x,y,n,m;
                cin>>x>>y>>n>>m;
                c[++n1].x=y,c[n1].y1=x,c[n1].y2=n,c[n1].k=1;
                c[++n1].x=m,c[n1].y1=x,c[n1].y2=n,c[n1].k=-1;
                b[++n2]=x,b[++n2]=n;
            }
            std::sort(c+1,c+n1+1,cmp);
            std::sort(b+1,b+n2+1);
            u len(std::unique(b+1,b+n2+1)-b-1);
            u ans(0);
            for(ri i(1); i<n1; ++i) {
                u _l(std::lower_bound(b+1,b+len+1,c[i].y1)-b);
                u _r(std::lower_bound(b+1,b+len+1,c[i].y2)-b);
                xds::update(1,_l,_r-1,c[i].k);
                ans+=(xds::a[1].v*(c[i+1].x-c[i].x));
            }
            //printf("Test case #%lld
",cas);
            //printf("Total explored area: %lld
",ans);
            std::cout<<ans;
        }
    }

}

int main() {

    //freopen("x.txt","r",stdin);
    std::ios::sync_with_stdio(false);
    mainstay::solve();

}
原文地址:https://www.cnblogs.com/ling-zhi/p/11784939.html