[P5490] [テンプレート]の走査線 - セグメントツリー

シーク(N- \)\矩形領域、および

解決

矩形に\(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;
}

おすすめ

転載: www.cnblogs.com/mollnn/p/12291186.html