• hdu4614 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.

    题意:有 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.
    ");
    106                 else printf("%d %d
    ",minn,maxx);
    107             }
    108             else if(t==2){
    109                 int a,b;
    110                 scanf("%d%d",&a,&b);
    111                 printf("%d
    ",update2(1,0,n-1,a,b));
    112             }
    113         }
    114         printf("
    ");
    115     }
    116     return 0;
    117 }
    View Code
  • 相关阅读:
    java之认识基本数据类型及其封装类装箱和拆箱总结
    java之集合类特性对比分析列表
    <转>泛型的内部原理:类型擦除以及类型擦除带来的问题
    java之集合类框架的简要知识点:泛型的类型擦除
    java之方法覆盖的坑
    java入门概念个人理解之访问修饰符
    blog开篇
    卓越管理的实践技巧(4)如何才能给予有效的反馈 Guide to Giving Effective Feedback
    权限管理系统之组织管理
    卓越管理的实践技巧(3)推动团队管理的要点 Facilitation Essentials for Managers
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/6598481.html
Copyright © 2020-2023  润新知