Description
小爱整天收到花。她有N个花瓶标号从0到N-1。如果她收到F朵花,她会选择一个花瓶A,尝试去放花进去那个花瓶。如果那个花瓶已经有花,她就顺序地找下一个,直到所有花都放完或者后面没有花瓶了。有时她会清理花瓶,把花瓶A到B(A<=B)之间的花全扔了。
Input
第一行两个整数N和M代表花瓶数和操作数。
然后M行每行第一个数字是K(1或2)。如果K是1,那么再输入A和F,如果K是2,那么输入A和B,含义如上所述。
Output
每个操作输出一行。
对于操作1,输出成功放花的第一个位置和最后一个位置,如果一朵花都没放,输出‘Can not put any one.’。
对于操作2,输出扔了多少花。
Sample Input
10 5
1 3 5
2 4 5
1 1 8
2 3 6
1 8 8
Sample Output
3 7
2
1 9
4
Can not put any one.
Data Constraint
对于40%的数据,有1≤N,M≤100。
对于100%的数据,有1≤N,M≤50000。
分析:用一个线段树维护一个区间的有花的花瓶数,对于询问随便搞搞就好。比较狗的是编号为0~N-1。
代码:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#define N 50001
#define inf 0x3f3f3f3f
#define fo(i,a,b) for (int i=a;i<=b;i++)
using namespace std;
int n,m,q,x,y,l,r,ans1,ans2,mid,g;
struct node{int x,q;};
node t[3*N];
void change(int p,int l,int r,int x,int y,int c)
{
if ((l==x) && (r==y))
{
if (c==0) t[p].x=0,t[p].q=0;
else t[p].x=r-l+1,t[p].q=1;
return;
}
if (t[p].q==c) return;
int mid=(l+r)/2;
if (t[p].q!=2) t[p*2].q=t[p*2+1].q=t[p].q;
if (t[p].q==1) t[p*2].x=mid-l+1,t[p*2+1].x=r-mid;
if (t[p].q==0) t[p*2].x=0,t[p*2+1].x=0;
t[p].q=2;
if (y<=mid) change(p*2,l,mid,x,y,c);
else
{
if (x>=mid+1) change(p*2+1,mid+1,r,x,y,c);
else
{
change(p*2,l,mid,x,mid,c);
change(p*2+1,mid+1,r,mid+1,y,c);
}
}
t[p].x=t[p*2].x+t[p*2+1].x;
}
int find(int p,int l,int r,int x,int y)
{
if ((l==x) && (r==y))
{
return t[p].x;
}
if (t[p].q==1)
{
return y-x+1;
}
if (t[p].q==0)
{
return 0;
}
int sum=0;
int mid=(l+r)/2;
if (y<=mid) sum+=find(p*2,l,mid,x,y);
else
{
if (x>=mid+1) sum+=find(p*2+1,mid+1,r,x,y);
else
{
sum+=find(p*2,l,mid,x,mid);
sum+=find(p*2+1,mid+1,r,mid+1,y);
}
}
return sum;
}
int main()
{
scanf("%d%d",&n,&m);
fo(i,1,m)
{
scanf("%d%d%d",&q,&x,&y);
if (q==1)
{
x++;
l=x; r=n; ans1=inf;
while (l<=r)
{
mid=(l+r)/2;
g=mid-x+1;
if (g-find(1,1,n,x,mid)!=0)
{
r=mid-1;
ans1=min(ans1,mid);
}
else l=mid+1;
}
l=x; r=n; ans2=inf;
y=min(y,n-x+1-find(1,1,n,x,n));
while (l<=r)
{
mid=(l+r)/2;
g=mid-x+1;
if (g-find(1,1,n,x,mid)>=y)
{
r=mid-1;
ans2=min(ans2,mid);
}
else l=mid+1;
}
if (find(1,1,n,x,ans2)==ans2-x+1) printf("Can not put any one.\n");
else printf("%d %d\n",ans1-1,ans2-1);
change(1,1,n,x,ans2,1);
}
else
{
x++; y++;
ans1=find(1,1,n,x,y);
change(1,1,n,x,y,0);
printf("%d\n",ans1);
}
}
}