欢迎来到SFWR的博客

P5490 【模板】扫描线

 

 


学得好费力啊

好久没写线段树了,复习了一下才学的,结果还是好多锅,导致现在还有点蒙蔽

再搞搞


#include<bits/stdc++.h>
using namespace std;
const int bow=1000010;
#define ln now<<1
#define rn now<<1|1
#define lll long long
int n,m,a,b,c,d;
int raw[bow<<1];
struct TREE{int l,r,sum;lll len;}te[bow<<2];
struct SL{int l,r,h,mk;}line[bow<<1];
int cmp(SL x,SL y){return x.h<y.h;}
void build(int now,int l,int r)
{
    te[now]=(TREE){l,r,0,0};
    if(l==r)return;
    int mid=(l+r)>>1;
    build(ln,l,mid);
    build(rn,mid+1,r);
}
void pushdown(int now,int l,int r)
{
    int rr=raw[te[now].r+1],ll=raw[te[now].l];
    if(te[now].sum)te[now].len=rr-ll;
    else if(l==r)te[now].len=0;
    else te[now].len=te[ln].len+te[rn].len;
}
void add(int now,int l,int r,int mark)
{
    int rr=raw[te[now].r+1],ll=raw[te[now].l];
    if(rr<=l||ll>=r)return;
    if(ll>=l&&rr<=r)te[now].sum+=mark;
    else{
    add(ln,l,r,mark);
    add(rn,l,r,mark);        
    }
    pushdown(now,l,r);
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a>>b>>c>>d;
        raw[i*2-1]=a;
        raw[i*2]=c;
        line[i*2-1]=(SL){a,c,b,1};
        line[i*2]=(SL){a,c,d,-1};
    }
    n<<=1;
    sort(line+1,line+1+n,cmp);
    sort(raw+1,raw+1+n);
    int tot=unique(raw+1,raw+1+n)-raw-1;
    build(1,1,tot-1);
    lll ans=0;
    for(int i=1;i<n;i++)
    {
        add(1,line[i].l,line[i].r,line[i].mk);
        ans+=1ll*te[1].len*(line[i+1].h-line[i].h);
    }
    cout<<ans;
}

 

posted @ 2019-09-04 16:37  SFWR  Views(169)  Comments(0Edit  收藏  举报