线段树+二分区间
用线段树维护某一段内还有多少个花瓶可以用,二分确定插入的左右界.....
2 10 5 1 3 5 2 4 5 1 1 8 2 3 6 1 8 8 10 6 1 2 5 2 3 4 1 0 8 2 2 5 1 4 4 1 2 3
[pre]3 7 2 1 9 4 Can not put any one. 2 6 2 0 9 4 4 5 2 3 [/pre]
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn=60050; int sum[maxn<<2],col[maxn<<2]; int n,m,leftbound,rightbound,F,A,B; void init() { memset(sum,0,sizeof(sum)); memset(col,-1,sizeof(col)); } void push_up(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void build(int l,int r,int rt) { if(l==r) { sum[rt]=1; return ; } int m=(l+r)/2; build(lson); build(rson); push_up(rt); } void push_down(int len,int rt) { if(col[rt]!=-1) { col[rt<<1]=col[rt<<1|1]=col[rt]; sum[rt<<1]=(len-len/2)*col[rt]; sum[rt<<1|1]=(len/2)*col[rt]; col[rt]=-1; } } int query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) return sum[rt]; push_down(r-l+1,rt); int m=(l+r)/2; int ret=0; if(L<=m) ret+=query(L,R,lson); if(R>m) ret+=query(L,R,rson); return ret; } void Update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&r<=R) { col[rt]=c; sum[rt]=(r-l+1)*c; return ; } push_down(r-l+1,rt); int m=(l+r)/2; if(L<=m) Update(L,R,c,lson); if(R>m) Update(L,R,c,rson); push_up(rt); } void showit(int l,int r,int rt) { cout<<"rt: "<<rt<<" left "<<l<<" right "<<r<<" sum "<<sum[rt]<<" col: "<<col[rt]<<endl; if(l>=r) return ; int m=(l+r)/2; showit(lson);showit(rson); } int get_left_point(int x) { int ans=-1; int low=x,high=n,mid; int w; while(low<=high) { mid=(low+high)/2; w=query(x,mid,1,n,1); if(!w) low=mid+1; else ans=mid,high=mid-1; } return ans; } int get_right_point() { int ans=-1; int low=leftbound,high=n,mid; int w; B=min(B,query(low,n,1,n,1)); while(low<=high) { mid=(low+high)/2; w=query(leftbound,mid,1,n,1); if(w>=B) high=mid-1; else low=mid+1; if(w==B) ans=mid; } return ans; } int main() { int T_T; scanf("%d",&T_T); while(T_T--) { scanf("%d%d",&n,&m); init(); build(1,n,1); while(m--) { scanf("%d%d%d",&F,&A,&B); A++; if(F==1) { if(!query(A,n,1,n,1)||B==0) { puts("Can not put any one."); continue; } leftbound=get_left_point(A); rightbound=get_right_point(); printf("%d %d\n",leftbound-1,rightbound-1); Update(leftbound,rightbound,0,1,n,1); } else if(F==2) { B++; printf("%d\n",B-A+1-query(A,B,1,n,1)); Update(A,B,1,1,n,1); } } putchar(10); } return 0; }