Luogu P5490 扫描线

Posted coder-cjh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P5490 扫描线相关的知识,希望对你有一定的参考价值。

模板题,想象一条线从左边扫到右边,只有在矩阵边界才会产生影响,所以我们离散化缩小数据范围,再用线段树维护扫描线上的情况,得出结果

#include<bits/stdc++.h>
#define ls k<<1
#define rs k<<1|1
#define int long long//注意要开longlong
using namespace std;
const int N=1e6+5;
int val[N<<1];
struct Seg_Tree
    int l,r,sum,cnt;
tr[N<<2];
inline void build(int k,int l,int r)
    tr[k].l=l,tr[k].r=r;
    if(l==r)return;
    int mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);

inline void pushup(int k)
    if(tr[k].cnt) tr[k].sum=val[tr[k].r+1]-val[tr[k].l];
    else tr[k].sum=tr[ls].sum+tr[rs].sum;//下传标记

inline void add(int k,int x,int y,int v)
    if(tr[k].l>y||tr[k].r<x)return;
    if(x<=tr[k].l&&tr[k].r<=y)
        tr[k].cnt+=v;
        pushup(k);
        return;
    
    add(ls,x,y,v);
    add(rs,x,y,v);
    pushup(k);

int n,cnt,tot,book[N<<2];
struct node
    int x,yl,yr,flag;
e[N<<1];
bool cmp(node a,node b)return a.x<b.x||(a.x==b.x&&a.flag>b.flag);
signed main()
    scanf("%lld",&n);
    for(int i=1,xl,xr,yl,yr;i<=n;i++)
        scanf("%lld%lld%lld%lld",&xl,&yl,&xr,&yr);
        book[++cnt]=yl;book[++cnt]=yr;
        e[++tot].x=xl;e[tot].yl=yl;e[tot].yr=yr;e[tot].flag=1;
        e[++tot].x=xr;e[tot].yl=yl;e[tot].yr=yr;e[tot].flag=-1;//离散化
    
    sort(book+1,book+cnt+1);
    int h=unique(book+1,book+cnt+1)-book-1;
    for(int i=1;i<=tot;i++)
        int pos1=lower_bound(book+1,book+h+1,e[i].yl)-book;
        int pos2=lower_bound(book+1,book+h+1,e[i].yr)-book;
        val[pos1]=e[i].yl;val[pos2]=e[i].yr;
        e[i].yl=pos1;e[i].yr=pos2;//记录
    
    sort(e+1,e+tot+1,cmp);
    build(1,1,tot);
    int ans=0;
    for(int i=1;i<=tot;i++)
        add(1,e[i].yl,e[i].yr-1,e[i].flag);
        ans+=tr[1].sum*(e[i+1].x-e[i].x);//得出答案
    
    cout<<ans<<endl;

 

以上是关于Luogu P5490 扫描线的主要内容,如果未能解决你的问题,请参考以下文章

线段树扫描线

扫描线进阶

luogu_P5490 模板扫描线

luogu5193 炸弹 (扫描线)

Luogu1382 楼房 (线段树 扫描线)

luogu5490POJ1151模板扫描线 /Atlantis (求矩形面积并)