题解 P5490 【【模板】扫描线】
题解
看了怎么多题解,竟然没有一篇是下传标记的。
我来写一份常规的下传标记的做法。
我们需要维护区间最小值和最小值的个数
对于一个询问,如果区间最小值>0,那么返回区间长长度,否则说明区间有些地方是0,那么答案就是区间长度-最小值个数(长度)
然后就是普通线段树操作了,不需要标记用优化。
代码
#include<bits/stdc++.h>
using namespace std;
#define next Next
#define last Last
#define int long long
const int N=1e6+5;
int n,gs,len,b[N],mi[N*4],lazy[N*4],sum[N*4],Len[N*4];
struct node{
int val,l,r,opt;
}a[N];
/*char buf[1<<21],*p1=buf,*p2=buf;
inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}*/
#define gc getchar
inline int read()
{
int ret=0,f=0;char c=gc();
while(!isdigit(c)){if(c=='-')f=1;c=gc();}
while(isdigit(c)){ret=ret*10+c-48;c=gc();}
if(f)return -ret;return ret;
}
void pushup(int nod)
{
mi[nod]=min(mi[nod*2],mi[nod*2+1]);
if(mi[nod]==mi[nod*2])sum[nod]=sum[nod*2];
else sum[nod]=0;
if(mi[nod]==mi[nod*2+1])sum[nod]+=sum[nod*2+1];
}
void pushdown(int nod)
{
if(lazy[nod]==0)return;
mi[nod*2]+=lazy[nod];
mi[nod*2+1]+=lazy[nod];
lazy[nod*2]+=lazy[nod];
lazy[nod*2+1]+=lazy[nod];
lazy[nod]=0;
}
void build(int nod,int l,int r)
{
Len[nod]=b[r+1]-b[l];
if(l==r)
{
sum[nod]=Len[nod];
return;
}
int mid=(l+r)/2;
build(nod*2,l,mid);
build(nod*2+1,mid+1,r);
pushup(nod);
}
void change(int nod,int l,int r,int L,int R,int val)
{
if(l==L&&r==R)
{
mi[nod]+=val;
lazy[nod]+=val;
return;
}
pushdown(nod);
int mid=(l+r)/2;
if(R<=mid)change(nod*2,l,mid,L,R,val);
else if(L>mid)change(nod*2+1,mid+1,r,L,R,val);
else{
change(nod*2,l,mid,L,mid,val);
change(nod*2+1,mid+1,r,mid+1,R,val);
}
pushup(nod);
}
int find(int nod,int l,int r,int L,int R)
{
if(l==L&&r==R)
{
if(mi[nod]>0)return Len[nod];
return Len[nod]-sum[nod];
}
pushdown(nod);
int mid=(l+r)/2;
if(R<=mid)return find(nod*2,l,mid,L,R);
else if(L>mid)return find(nod*2+1,mid+1,r,L,R);
else return find(nod*2,l,mid,L,mid)+find(nod*2+1,mid+1,r,mid+1,R);
pushup(nod);
}
bool cmp(node a,node b)
{
return a.val<b.val;
}
signed main()
{
n=read();
for(int i=1;i<=n;i++)
{
int x1=read(),y1=read(),x2=read(),y2=read();
a[++gs]=(node){x1,y1,y2,1};
a[++gs]=(node){x2,y1,y2,-1};
b[++len]=y1;
b[++len]=y2;
}
sort(b+1,b+len+1);
len=unique(b+1,b+len+1)-b-1;
build(1,1,len-1);
for(int i=1;i<=gs;i++)
{
a[i].l=lower_bound(b+1,b+len+1,a[i].l)-b;
a[i].r=lower_bound(b+1,b+len+1,a[i].r)-b;
}
sort(a+1,a+gs+1,cmp);
int ans=0;
for(int i=1;i<gs;i++)
{
if(a[i].l<a[i].r)change(1,1,len-1,a[i].l,a[i].r-1,a[i].opt);
ans=ans+find(1,1,len-1,1,len-1)*(a[i+1].val-a[i].val);
}
cout<<ans;
} 
京公网安备 11010502036488号