题意:给出两种操作,一种是从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;
}