题意:
有N个花瓶..每个花瓶至多放一朵花..每次的操作是1、从某个序号的花瓶开始..F朵花到空的花瓶..若后面的空花瓶不足F..则把剩下的花丢掉..当后面没有一个空花瓶..输出Can not put any one...2、把[ L,R ]范围内所有的花拿掉...并输出这个区间之前有多少花..
题解:
用线段树的区间查询与更新来维护当前的情况...为了方便统计..对于一个花瓶..若空着的就为1..有花就为0...线段树中父亲节点和子节点的更新关系是求和...在进行操作1 x F时..先用二分+线段树query找出区间[ x,n ]空着的花瓶的最左与最右.. 再query统计这段里的空花瓶是否小于等于F..如果是大于了..那么再在这个区间内二分+线段树query找出最终最右的位置..确定了位置后..update更新这个区间都为0..在进行操作2 l r 时..就直接query得出 [ l , r ] 有多少个空的...(r-l+1)-query就是所要的输出..再更新 [ l , r ] 区间都为1...
有个很恶心的地方...F居然可以为0...根据题意..输出Can not put any one..
Program:
#include<iostream> #include<stdio.h> #include<string.h> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> #define ll long long #define oo 1000000007 #define pi acos(-1.0) #define MAXN 50005 #define MAXM 50005 using namespace std; int sum[MAXN<<2],col[MAXN<<2],n; void PushDown(int len,int now) { if (col[now]==-1) return; col[now<<1]=col[(now<<1)|1]=col[now]; sum[now<<1]=(len-(len>>1))*col[now]; sum[(now<<1)|1]=(len>>1)*col[now]; col[now]=-1; return; } void update(int L,int R,int c,int l,int r,int now) { if (L<=l && R>=r) { sum[now]=(r-l+1)*c; col[now]=c; return; } PushDown(r-l+1,now); int mid=(r+l)>>1; if (L<=mid) update(L,R,c,l,mid,now<<1); if (R>mid) update(L,R,c,mid+1,r,(now<<1)|1); sum[now]=sum[now<<1]+sum[(now<<1)|1]; return; } int query(int L,int R,int l,int r,int now) { if (L<=l && R>=r) return sum[now]; PushDown(r-l+1,now); int ans=0,mid=(r+l)>>1; if (L<=mid) ans+=query(L,R,l,mid,now<<1); if (R>mid) ans+=query(L,R,mid+1,r,(now<<1)|1); return ans; } int findmin(int x) { int mid,l,r,w; l=x-1,r=n+1; while (r-l>1) { mid=(r+l)>>1; w=query(x,mid,1,n,1); if (w) r=mid; else l=mid; } return r; } int findmax() { int mid,l,r,w; l=0,r=n+1; while (r-l>1) { mid=(r+l)>>1; w=query(mid,n,1,n,1); if (w) l=mid; else r=mid; } return l; } int bsearch(int l,int r,int x,int len) { int mid,w,L=l+1; while (r-l>1) { mid=(l+r)>>1; w=query(L,mid,1,n,1); if (w<len) l=mid; else r=mid; } return r; } int main() { int T,i,m; scanf("%d",&T); while (T--) { scanf("%d%d",&n,&m); memset(sum,0,sizeof(sum)); memset(col,-1,sizeof(col)); for (i=1;i<=n;i++) update(i,i,1,1,n,1); while (m--) { int tp,x,y; scanf("%d%d%d",&tp,&x,&y); if (tp==1) { x++; if (!y || !query(x,n,1,n,1)) { printf("Can not put any one.\n"); continue; } int l=findmin(x); int r=findmax(); if (query(l,r,1,n,1)>y) r=bsearch(l-1,r+1,x,y); printf("%d %d\n",l-1,r-1); update(l,r,0,1,n,1); }else { x++,y++; printf("%d\n",(y-x+1)-query(x,y,1,n,1)); update(x,y,1,1,n,1); } } printf("\n"); } return 0; }