http://www.lydsy.com/JudgeOnline/problem.php?id=4592
注意操作1 先挖再补,就是补的范围可以包含挖的范围
SHOI2015 的题 略水啊(逃)
#include<cstdio> #include<iostream> #define N 200001 using namespace std; #define max(x,y) ((x)>(y) ? (x) : (y)) #define min(x,y) ((x)<(y) ? (x) : (y)) struct node { int L0,R0,mx0; int siz; node operator + (node p) const { node A; A.L0=L0; if(L0==siz) A.L0+=p.L0; A.R0=p.R0; if(p.R0==p.siz) A.R0+=R0; A.mx0=max(mx0,p.mx0); A.mx0=max(A.mx0,R0+p.L0); A.siz=siz+p.siz; return A; } }tr[N<<2]; int sum1[N<<2]; int tag[N<<2]; int tot; int n; void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } void build(int k,int l,int r) { tag[k]=-1; tr[k].L0=tr[k].R0=tr[k].mx0=0; tr[k].siz=sum1[k]=r-l+1; if(l==r) return; int mid=l+r>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); } void tagging(int k,int w) { if(w) sum1[k]=tr[k].siz,tr[k].L0=tr[k].R0=tr[k].mx0=0; else sum1[k]=0,tr[k].L0=tr[k].R0=tr[k].mx0=tr[k].siz; tag[k]=w; } void down(int k) { tagging(k<<1,tag[k]); tagging(k<<1|1,tag[k]); tag[k]=-1; } void change(int k,int l,int r,int opl,int opr,int w) { if(l>=opl && r<=opr) { tagging(k,w); return; } if(tag[k]!=-1) down(k); int mid=l+r>>1; if(opl<=mid) change(k<<1,l,mid,opl,opr,w); if(opr>mid) change(k<<1|1,mid+1,r,opl,opr,w); sum1[k]=sum1[k<<1]+sum1[k<<1|1]; tr[k]=tr[k<<1]+tr[k<<1|1]; } void query(int k,int l,int r,int opl,int opr,int w) { if(l>=opl && r<=opr) { if(w) tot+=sum1[k]; else tot+=tr[k].siz-sum1[k]; return; } if(tag[k]!=-1) down(k); int mid=l+r>>1; if(opl<=mid) query(k<<1,l,mid,opl,opr,w); if(opr>mid) query(k<<1|1,mid+1,r,opl,opr,w); } int find(int L,int cnt) { int R=L,mid; int l=L,r=n; while(l<=r) { mid=l+r>>1; tot=0; query(1,1,n,L,mid,0); if(tot<=cnt) l=mid+1,R=mid; else r=mid-1; } return R; } node Query(int k,int l,int r,int opl,int opr) { if(l==opl && r==opr) return tr[k]; if(tag[k]!=-1) down(k); int mid=l+r>>1; if(opr<=mid) return Query(k<<1,l,mid,opl,opr); if(opl>mid) return Query(k<<1|1,mid+1,r,opl,opr); return Query(k<<1,l,mid,opl,mid)+Query(k<<1|1,mid+1,r,mid+1,opr); } int main() { int m; read(n); read(m); build(1,1,n); int ty,l,r,ll,rr; int pos; while(m--) { read(ty); read(l); read(r); if(!ty) change(1,1,n,l,r,0); else if(ty==1) { tot=0; query(1,1,n,l,r,1); change(1,1,n,l,r,0); read(ll); read(rr); if(!tot) continue; pos=find(ll,tot); //从l起,tot个1能补到哪儿 change(1,1,n,ll,min(pos,rr),1); } else printf("%d ",Query(1,1,n,l,r).mx0); } }