题意:给出两种操作,一种是从A开始向后放花,一种是把a到b的花全部扔掉。放过的位置就不能再次放
显然线段树,加上两种标记,一种是这块是满的,一种是这块是空的,然后第一种操作答案带上三个值
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #define LL long long #define fo(i,a,b) for(int i=a;i<=b;i++) #define dfo(i,a,b) for(int i=a;i>=b;i--) using namespace std; inline LL read() { LL d=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();} return d*f; } #define N 100005 #define inf 2000000000 struct ansss { int first,last,ans; }ans; int ls[N*3],rs[N*3],z0[N*3],w0[N*3],sum[N*3],la[N*3]; int n,m; ansss pushans(ansss a,ansss b) { ansss ret; ret.first=min(a.first,b.first); ret.last=max(a.last,b.last); ret.ans=a.ans+b.ans; return ret; } void pushup(int k) { sum[k]=sum[k<<1]+sum[k<<1|1]; z0[k]=min(z0[k<<1],z0[k<<1|1]); w0[k]=max(w0[k<<1],w0[k<<1|1]); if(z0[k]==inf)la[k]=1; } void man(int k) { sum[k]=rs[k]-ls[k]+1; z0[k]=inf;w0[k]=-1; } void clear(int k) { sum[k]=0; z0[k]=ls[k];w0[k]=rs[k]; } ansss checkans(ansss k) { if(k.ans==0) { k.first=inf; k.last=-1; } return k; } void build(int k,int l,int r) { if(l==r) { ls[k]=rs[k]=l; clear(k); la[k]=0; return; } int mid=(l+r)>>1; build(k<<1,l,mid);build(k<<1|1,mid+1,r); ls[k]=ls[k<<1];rs[k]=rs[k<<1|1]; pushup(k); } void pushlazy(int k) { if(la[k]==0)return; if(la[k]==1) { man(k<<1);man(k<<1|1); la[k<<1]=la[k<<1|1]=1; la[k]=0; return ; } if(la[k]==2) { clear(k<<1);clear(k<<1|1); la[k<<1]=la[k<<1|1]=2; la[k]=0; return; } } ansss F(int k,int l,int r,int f) { ansss ret; if(ls[k]==l&&rs[k]==r) { int tt=r-l+1; if(tt-sum[k]==0||f==0) { ret.first=inf;ret.last=-1; ret.ans=0; return checkans(ret); } if(f>=tt-sum[k]) { ret.first=z0[k];ret.last=w0[k]; ret.ans=tt-sum[k]; z0[k]=inf;w0[k]=-1; sum[k]=tt; la[k]=1; return checkans(ret); } pushlazy(k); int mid=(l+r)>>1; ansss t=F(k<<1,l,mid,f); ret=F(k<<1|1,mid+1,r,f-t.ans); ret=pushans(t,ret); pushup(k); return checkans(ret); } pushlazy(k); int mid=(ls[k]+rs[k])>>1; if(l>mid)ret=F(k<<1|1,l,r,f);else { if(r<=mid)ret=F(k<<1,l,r,f);else { ansss t=F(k<<1,l,mid,f); ret=F(k<<1|1,mid+1,r,f-t.ans); ret=pushans(t,ret); } } pushup(k); return checkans(ret); } int R(int k,int l,int r) { int ret=0; if(ls[k]==l&&rs[k]==r) { ret=sum[k]; clear(k); la[k]=2; return ret; } pushlazy(k); int mid=(ls[k]+rs[k])>>1; if(r<=mid)ret=R(k<<1,l,r);else { if(l>mid)ret=R(k<<1|1,l,r);else { ret=R(k<<1,l,mid)+R(k<<1|1,mid+1,r); } } pushup(k); return ret; } int main() { freopen("vase.in","r",stdin); freopen("vase.out","w",stdout); n=read(),m=read(); build(1,0,n-1); fo(i,1,m) { int ch=read(),x=read(),y=read(); if(ch==1) { ans=F(1,x,n-1,y); if(ans.ans<=0)puts("Can not put any one."); else printf("%d %d\n",ans.first,ans.last); }else printf("%d\n",R(1,x,y)); } return 0; }