zoukankan      html  css  js  c++  java
  • HDU4614Vases and Flowers 二分+线段树;

    参考:https://blog.csdn.net/ophunter_lcm/article/details/9879495
     
    题意:
    有n个花瓶,有两种操作,1.从a开始放b朵花,有花的花瓶跳过,2.把a到b间的花全部拿下来。
    思路:
     
    线段树+二分
    利用二分确定区间,这样就可以是线段树实现更简单的问题:
    1)对区间进行全部设置为1的操作
    2)对区间进行全部清零的操作 
     
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <queue>
    #include <list>
    #include <iterator>
    
    using namespace std;
    #define lson l , mid , rt << 1
    #define rson mid + 1 , r , rt << 1 | 1
    #define debug(x) cerr << #x << " = " << x << "
    ";
    
    typedef long long ll;
    const int maxn =  50009;
    const int mdd = 10007;
    int n,m;
    struct node {
        int l,r;    
        int lazy,sum;
    }st[maxn<<2];
    
    void build(int l,int r,int rt)
    {
        st[rt].l = l,st[rt].r = r;
        st[rt].sum = 0;
        st[rt].lazy = -1;
        int mid = (l+r)>>1;
        if(l==r)return;
        build(lson);
        build(rson);
    }
    inline void pushup(int rt)
    {
        st[rt].sum = st[rt<<1].sum + st[rt<<1|1].sum;
    }
    inline void pushdown(int rt)
    {
        
        if(st[rt].lazy==1)
        {
            st[rt<<1].lazy = st[rt<<1|1].lazy = st[rt].lazy;
            st[rt<<1].sum = st[rt<<1].r - st[rt<<1].l + 1;
            st[rt<<1|1].sum = st[rt<<1|1].r - st[rt<<1|1].l + 1;
        }
        else if(st[rt].lazy==0)
        {    
            st[rt<<1].lazy = st[rt<<1|1].lazy = st[rt].lazy;
            st[rt<<1].sum = st[rt<<1|1].sum = 0;
        }
    
        st[rt].lazy = -1;
    }
    int  query(int l,int r,int rt,int L,int R)
    {
        if(l>=L&&r<=R)
        {
            return st[rt].sum;
        }
        int mid = (l + r)>>1;
        pushdown(rt);
        int ans = 0;
        if(mid>=L)ans += query(l,mid,rt<<1,L,R);
        if(mid<R)ans += query(mid+1,r,rt<<1|1,L,R);
        return ans;
    }
    void update(int l,int r,int rt,int L,int R,int op)
    {
        if(l>=L&&r<=R)
        {
            if(op==1){
                st[rt].lazy = 1;
                st[rt].sum = r - l + 1;
            }
            else {
                st[rt].lazy = 0;
                st[rt].sum = 0;
            }
            return;
        }
        int mid = (r+l)>>1;
        pushdown(rt);
        if(mid>=L)update(l,mid,rt<<1,L,R,op);
        if(mid<R)update(mid+1,r,rt<<1|1,L,R,op);
        pushup(rt);
    }
    int bdfind(int st,int len)//二分查找
    {
        int le = st;
        int ri = n;
        int ans = -1;
        while(le <= ri)
        {
            int mid = (le + ri)>>1;
            int lenSum = query(1,n,1,st,mid);    //找有花的瓶子个数
            if(lenSum + len == mid - st + 1)
            {
                ans =  mid;        //不要直接return,要找最小的。        
                ri = mid - 1;
            }
            else if(lenSum + len < mid - st +1) 
            {
                ri = mid - 1;
            }
            else le = mid + 1;
        }
        return ans;//找到在【st,mid】间符合len个空瓶;
    }
    int main(){
        // freopen("input","r",stdin);
         int t;
         scanf("%d", &t);
         while(t--)
         {
             scanf("%d%d", &n, &m);
             build(1,n,1);
             while(m--)
             {
                 int op;
                 int a,b,c;
                 scanf("%d%d%d", & op, & a,& b);
                 if(op==1)
                 {
                     a++;
                     int st = bdfind(a,1);
                     if(st==-1)
                         puts("Can not put any one.");
                     else 
                     {
                         int tmp = query(1,n,1,st,n);
                         tmp = (n - st + 1) - tmp;    //空瓶个数
                         b = min(tmp,b);
                         int ed = bdfind(a, b);
                         printf("%d %d
    ",st-1,ed-1);
                         update(1,n,1,st,ed,1);
                     }
                 }
                 else 
                 {
                     a++,b++;
                     printf("%d
    ",query(1,n,1,a,b));
                     update(1,n,1,a,b,0);
                 }
             }
             puts("");
         }
        return 0;
    }
  • 相关阅读:
    学习MyBatis时报的错
    Day01
    PAT乙级01
    基于python-django框架的支付宝支付案例
    单线程与多线程的应用 --Python3
    Python异常 --Python
    有四个数字能组成多少个互不相同的三位数 --Python
    with as用法 --Python
    采用霍夫曼编码(Huffman)画出字符串各字符编码的过程并求出各字符编码 --多媒体技术与应用
    函数和代码复用 --Python
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/9021564.html
Copyright © 2011-2022 走看看