Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N-1. When she receive some flowers, she will try to put them in the vases, one flower in one vase. She randomly choose the vase A and try to put a flower in the vase. If the there is no flower in the vase, she will put a flower in it, otherwise she skip this vase. And then she will try put in the vase A+1, A+2, ..., N-1, until there is no flower left or she has tried the vase N-1. The left flowers will be discarded. Of course, sometimes she will clean the vases. Because there are too many vases, she randomly choose to clean the vases numbered from A to B(A <= B). The flowers in the cleaned vases will be discarded.

题意:有 0~n-1 共 n 个花瓶,一个花瓶可以插一束花,现在有两个操作,一个是从 A 号花瓶开始插 k 束花,若花瓶有花就顺延到下一个花瓶,直到插完 k 束花或插完 n-1 号花瓶,问她插的第一个和最后一个花瓶编号。第二个操作是清空一段区间的花,问共丢掉多少花。

线段树保存区间空瓶数、首个空瓶和末个空瓶。树上二分查找 k 个空瓶,并更新最大最小空瓶位置。区间清除。

  1 #include<stdio.h>
  2 #include<string.h>
  3 const int maxm=50006;
  4 const int INF=0x3f3f3f3f;
  5 
  6 int st[maxm<<2],ma[maxm<<2],mi[maxm<<2];
  7 int ch[maxm<<2];
  8 int maxx,minn,k;
  9 
 10 inline int max(int a,int b){return a>b?a:b;}
 11 inline int min(int a,int b){return a<b?a:b;}
 12 
 13 void build(int o,int l,int r){
 14     ma[o]=r;
 15     mi[o]=l;
 16     st[o]=r-l+1;
 17     ch[o]=0;
 18     if(l==r)return;
 19     int m=l+((r-l)>>1);
 20     build(o<<1,l,m);
 21     build(o<<1|1,m+1,r);
 22 }
 23 
 24 void pushdown(int o,int l,int r){
 25     if(ch[o]==1){
 26         ch[o<<1]=ch[o<<1|1]=1;
 27         int m=l+((r-l)>>1);
 28         st[o<<1]=st[o<<1|1]=0;
 29         ma[o<<1]=ma[o<<1|1]=-1;
 30         mi[o<<1]=mi[o<<1|1]=INF;
 31         ch[o]=0;
 32     }
 33     else if(ch[o]==2){
 34         ch[o<<1]=ch[o<<1|1]=2;
 35         int m=l+((r-l)>>1);
 36         st[o<<1]=m-l+1;
 37         st[o<<1|1]=r-m;
 38         ma[o<<1]=m;
 39         ma[o<<1|1]=r;
 40         mi[o<<1]=l;
 41         mi[o<<1|1]=m+1;
 42         ch[o]=0;
 43     }
 44 }
 45 
 46 void update1(int o,int l,int r,int ql,int qr){
 47     if(ql<=l&&qr>=r){
 48         if(k>=st[o]){
 49             k-=st[o];
 50             maxx=max(maxx,ma[o]);
 51             minn=min(minn,mi[o]);
 52             ma[o]=-1;
 53             mi[o]=INF;
 54             st[o]=0;
 55             ch[o]=1;
 56             return;
 57         }
 58         else if(l==r)return;
 59     }
 60     pushdown(o,l,r);
 61     int m=l+((r-l)>>1);
 62     if(ql<=m&&k)update1(o<<1,l,m,ql,qr);
 63     if(qr>=m+1&&k)update1(o<<1|1,m+1,r,ql,qr);
 64     ma[o]=max(ma[o<<1],ma[o<<1|1]);
 65     mi[o]=min(mi[o<<1],mi[o<<1|1]);
 66     st[o]=st[o<<1]+st[o<<1|1];
 67 }
 68 
 69 int update2(int o,int l,int r,int ql,int qr){
 70     if(ql<=l&&qr>=r){
 71         int ans=r-l+1-st[o];
 72         st[o]=r-l+1;
 73         ma[o]=r;
 74         mi[o]=l;
 75         ch[o]=2;
 76         return ans;
 77     }
 78     pushdown(o,l,r);
 79     int m=l+((r-l)>>1);
 80     int ans=0;
 81     if(ql<=m)ans+=update2(o<<1,l,m,ql,qr);
 82     if(qr>=m+1)ans+=update2(o<<1|1,m+1,r,ql,qr);
 83     ma[o]=max(ma[o<<1],ma[o<<1|1]);
 84     mi[o]=min(mi[o<<1],mi[o<<1|1]);
 85     st[o]=st[o<<1]+st[o<<1|1];
 86     return ans;
 87 }
 88 
 89 int main(){
 90     int T;
 91     scanf("%d",&T);
 92     while(T--){
 93         int n,m;
 94         scanf("%d%d",&n,&m);
 95         build(1,0,n-1);
 96         for(int i=1;i<=m;++i){
 97             int t;
 98             scanf("%d",&t);
 99             if(t==1){
100                 int a;
101                 scanf("%d%d",&a,&k);
102                 maxx=-1;
103                 minn=INF;
104                 update1(1,0,n-1,a,n-1);
105                 if(maxx==-1&&minn==INF)printf("Can not put any one.\n");
106                 else printf("%d %d\n",minn,maxx);
107             }
108             else if(t==2){
109                 int a,b;
110                 scanf("%d%d",&a,&b);
111                 printf("%d\n",update2(1,0,n-1,a,b));
112             }
113         }
114         printf("\n");
115     }
116     return 0;
117 }
View Code