Vases and Flowers HDU

来源:互联网 发布:windows mobile软件 编辑:程序博客网 时间:2024/05/20 10:11
 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

210 51 3 52 4 51 1 82 3 61 8 810 61 2 52 3 41 0 82 2 51 4 41 2 3

Sample Output

[pre]3 721 94Can not put any one.2 620 944 52 3[/pre]

题意:有n个花瓶,每个花瓶中只能放一朵花。两种操作,一种是从A开始放F朵花,如果有的花瓶中已经有花则跳过这个花瓶,往下一个花瓶放;第二种是将区间[A,B]之间花瓶中的花清空。如果是第一种操作,输出这次放的花的左右端点;如果是第二种操作,输出这次总共清理出了多少支花。建立线段树,节点维护在相应的区间中,没有放入花的花瓶数目。有三种操作:一、查询某个区间中第k个没有插入花的花瓶位置;二、更新区间,使区间全部插入花;三、更新区间,使区间中的花瓶全部清空;

#include<stdio.h>#include<stdlib.h>#include<string.h>#define N 50010struct node{    int sum,b;//sum为在范围内的花数,b为判断是否全为空或全为满则为1,否则为0} tree[4*N];void build(int l,int r,int i){    int mid = (l + r)/2;    tree[i].sum = 0;    tree[i].b = 1;    if(l == r)        return ;    build(l, mid, i*2);    build(mid + 1,r,i*2+1);}void Set(int l,int r,int i){    int mid = (l + r)/2;    tree[i*2].b = tree[i*2+1].b = 1;    if(tree[i].sum == r - l +1)    {        tree[i*2].sum=mid-l+1;        tree[i*2+1].sum=r-mid;    }    else    {        tree[i*2].sum = 0;        tree[i*2+1].sum = 0;    }}int QL,QR,L,R,ans,n;void Put(int l,int r,int i){    if(ans<=0) return ;    int m = (l+r)/2;    if(L<=l&&r<=R&&tree[i].b)    {        if(!tree[i].sum)        {            int tans = ans;            ans -= (r-l+1);            tree[i].sum = r-l+1;            if(QL <0)                QL = l-1;            QR = r-1;        }        else        {            //跳动插花范围的右边值,R刚好是插完花的右边范围的最小值,除非超出花瓶数量,则为n            R += (r-l+1);            if(R>n) R=n;        }        return ;    }    if(tree[i].b)    Set(l,r,i);    tree[i].b=0;    if(L<=m) Put(l,m,i*2);    if(R>m) Put(m+1,r,i*2+1);    tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;    if(tree[i].sum==r-l+1||!tree[i].sum)        tree[i].b=1;}void Clear(int l,int r,int i){   int mid = (l+r)/2;   if(L<=l&&r<=R)   {      ans+= tree[i].sum;      tree[i].b = 1;      tree[i].sum = 0;      return ;   }   if(tree[i].b)   Set(l,r,i);   tree[i].b = 0;   if(L<=mid) Clear(l,mid,i*2);    if(R>mid) Clear(mid+1,r,i*2+1);    tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;    if(tree[i].sum==r-l+1||!tree[i].sum)        tree[i].b=1;}int main(){   int t,m,x;   scanf("%d",&t);   while(t--)   {      scanf("%d %d",&n,&m);      build(1,n,1);      while(m--)      {         scanf("%d %d",&x,&L);         L++;         if(x==1)         {            scanf("%d",&ans);            R = L+ans-1;            QL = QR = -1;            Put(1,n,1);            if(QR >=0)             printf("%d %d\n",QL,QR);                else                    printf("Can not put any one.\n");         }         else         {            scanf("%d",&R);            R++;            ans = 0;            Clear(1,n,1);            printf("%d\n",ans);         }      }      printf("\n");   }   return 0;}
原创粉丝点击