HDU 4614 Vases and Flowers(线段树)

描述

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.

Input

The first line contains an integer T, indicating the number of test cases.
For each test case, the first line contains two integers N(1 < N < 50001) and M(1 < M < 50001). N is the number of vases, and M is the operations of Alice. Each of the next M lines contains three integers. The first integer of one line is K(1 or 2). If K is 1, then two integers A and F follow. It means Alice receive F flowers and try to put a flower in the vase A first. If K is 2, then two integers A and B follow. It means the owner would like to clean the vases numbered from A to B(A <= B).

Output

For each operation of which K is 1, output the position of the vase in which Alice put the first flower and last one, separated by a blank. If she can not put any one, then output 'Can not put any one.'. For each operation of which K is 2, output the number of discarded flowers.
Output one blank line after each test case.

Sample Input
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

Sample Output
3 7
2
1 9
4
Can not put any one.

2 6
2
0 9
4
4 5
2 3

题意

爱丽丝有N个花瓶,编号0-N-1,有M个操作

当K=1时,表示从A开始直到插完B朵花后停止,输出第一朵花和最后一朵花插的位置,如果一朵都插不进去输出Can not put any one,如果瓶子不够插输出第一朵插和最后插的位子

当K=2时,表示主人要清空[A,B]花瓶里的花,输出清除了多少朵

题解

线段树区间更新延迟标记,区间查询

当K=1时

如果[A,B]中0的个数为0表示已经插满,输出Can not put any one

如果0的个数>=B朵花,表示可以插B朵

如果0的个数<B朵花,表示只能插0的个数朵花

A点开始二分[A+1,N],区间查询[A,mid]插花的数目,找到能插入B朵花的最左端qr,再二分[A,qr]找到第一个插入的最左端ql,然后得到区间[ql,qr],更新即可

当K=2时

把[A,B]的区间更新

代码

  1 #include<stdio.h>
  2 #include<algorithm>
  3 using namespace std;
  4 
  5 const int N=5e4+5;
  6 
  7 struct node
  8 {
  9     int l,r,sum,lazy;
 10 }a[N<<2];
 11 void PushUp(int rt)
 12 {
 13     a[rt].sum=a[rt<<1].sum+a[rt<<1|1].sum;
 14 }
 15 void PushDown(int rt)
 16 {
 17     if(a[rt].lazy!=-1)
 18     {
 19         a[rt<<1].lazy=a[rt<<1|1].lazy=a[rt].lazy;
 20         a[rt<<1].sum=a[rt].lazy*(a[rt<<1].r-a[rt<<1].l+1);
 21         a[rt<<1|1].sum=a[rt].lazy*(a[rt<<1|1].r-a[rt<<1|1].l+1);
 22         a[rt].lazy=-1;
 23     }
 24 }
 25 void Build(int l,int r,int rt)
 26 {
 27     a[rt].l=l;
 28     a[rt].r=r;
 29     a[rt].sum=0;
 30     a[rt].lazy=-1;
 31     if(l==r)return;
 32     int mid=(l+r)>>1;
 33     Build(l,mid,rt<<1);
 34     Build(mid+1,r,rt<<1|1);
 35 }
 36 void Update(int L,int R,int C,int l,int r,int rt)
 37 {
 38     if(L<=l&&r<=R)
 39     {
 40         a[rt].lazy=C;
 41         a[rt].sum=C*(r-l+1);
 42         return;
 43     }
 44     int mid=(l+r)>>1;
 45     PushDown(rt);
 46     if(L<=mid)Update(L,R,C,l,mid,rt<<1);
 47     if(R>mid)Update(L,R,C,mid+1,r,rt<<1|1);
 48     PushUp(rt);
 49 }
 50 int Query(int L,int R,int l,int r,int rt)
 51 {
 52 
 53     if(L<=l&&r<=R)
 54         return a[rt].sum;
 55     int mid=(l+r)>>1,sum=0;
 56     PushDown(rt);
 57     if(L<=mid)sum+=Query(L,R,l,mid,rt<<1);
 58     if(R>mid)sum+=Query(L,R,mid+1,r,rt<<1|1);
 59     PushUp(rt);
 60     return sum;
 61 }
 62 int main()
 63 {
 64     int t,n,m,x,y,op;
 65     scanf("%d",&t);
 66     while(t--)
 67     {
 68         scanf("%d%d",&n,&m);
 69         Build(1,n,1);
 70         for(int i=1;i<=m;i++)
 71         {
 72             scanf("%d%d%d",&op,&x,&y);
 73             x++;
 74             if(op==1)
 75             {
 76                 int cnt=n-x+1-Query(x,n,1,n,1),ql=x,qr=n;//x--n未插的个数
 77                 if(cnt==0)//全是花
 78                 {
 79                     printf("Can not put any one.\n");
 80                     continue;
 81                 }
 82                 else if(cnt>=y)//只能插y朵
 83                 {
 84                     int l=x,r=n;
 85                     while(l<=r)
 86                     {
 87                         int mid=(l+r)>>1;
 88                         cnt=mid-x+1-Query(x,mid,1,n,1);
 89                         if(cnt>=y)qr=mid,r=mid-1;
 90                         else l=mid+1;
 91                     }
 92                 }
 93                 else//只能插cnt朵
 94                 {
 95                     int l=x,r=n;
 96                     y=cnt;
 97                     while(l<=r)
 98                     {
 99                         int mid=(l+r)>>1;
100                         cnt=mid-x+1-Query(x,mid,1,n,1);
101                         if(cnt>=y)qr=mid,r=mid-1;
102                         else l=mid+1;
103                     }
104                 }
105                 ///二分左区间[x,qr]
106                 int l=x,r=qr;
107                 while(l<=r)
108                 {
109                     int mid=(l+r)>>1;
110                     cnt=qr-mid+1-Query(mid,qr,1,n,1);
111                     if(cnt>=y)ql=mid,l=mid+1;
112                     else r=mid-1;
113                 }
114                 Update(ql,qr,1,1,n,1);
115                 printf("%d %d\n",ql-1,qr-1);
116             }
117             if(op==2)
118             {
119                 y++;
120                 printf("%d\n",Query(x,y,1,n,1));
121                 Update(x,y,0,1,n,1);
122             }
123         }
124         printf("\n");
125     }
126     return 0;
127 }

猜你喜欢

转载自www.cnblogs.com/taozi1115402474/p/9291486.html