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 扫描线的主要内容,如果未能解决你的问题,请参考以下文章