zoukankan      html  css  js  c++  java
  • hdu 4614 Vases and Flowers 线段树

    题目链接

    一共n个盒子, 两种操作, 第一种是给出两个数x, y, 从第x个盒子开始放y朵花, 一个盒子只能放一朵, 如果某个盒子已经有了, 那么就跳过这个盒子放下面的盒子。 直到花放完了或者到了最后一个盒子。 输出放的第一朵花和最后一朵花的坐标, 如果一朵也没法放, 输出Can not put any one.

    第二种操作, 给出l, r, 求l, r区间内有多少朵花, 输出, 并且将l, r内的盒子全部变空。

    思路: 第二种操作比较简单, 区间查询然后区间置0就可以。

    第一种操作, 首先查询[x, n]内一共有多少个盒子是空的, 如果全是满的, 直接输出Can not put any one.  设num为空盒子的数量, 那么显然y = min(y, num)。

    接下来的问题就是找左右端点, 我是用的二分寻找左右端点, 具体的细节可以看代码。

    #include <iostream>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <set>
    #include <string>
    #include <queue>
    #include <stack>
    #include <bitset>
    using namespace std;
    #define pb(x) push_back(x)
    #define ll long long
    #define mk(x, y) make_pair(x, y)
    #define lson l, m, rt<<1
    #define mem(a) memset(a, 0, sizeof(a))
    #define rson m+1, r, rt<<1|1
    #define mem1(a) memset(a, -1, sizeof(a))
    #define mem2(a) memset(a, 0x3f, sizeof(a))
    #define rep(i, n, a) for(int i = a; i<n; i++)
    #define fi first
    #define se second
    typedef pair<int, int> pll;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int mod = 1e9+7;
    const int inf = 1061109567;
    const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    const int maxn = 5e4+5;
    int sum[maxn<<2], cnt[maxn<<2], n;
    void pushUp(int rt) {
        sum[rt] = sum[rt<<1]+sum[rt<<1|1];
    }
    void pushDown(int rt, int m) {
        if(~cnt[rt]) {
            cnt[rt<<1] = cnt[rt<<1|1] = cnt[rt];
            sum[rt<<1] = cnt[rt]*(m-(m>>1));
            sum[rt<<1|1] = cnt[rt]*(m>>1);
            cnt[rt] = -1;
        }
    }
    void update(int L, int R, int l, int r, int rt, int val) {
        if(L<=l&&R>=r) {
            cnt[rt] = val;
            sum[rt] = val*(r-l+1);
            return ;
        }
        pushDown(rt, r-l+1);
        int m = l+r>>1;
        if(L<=m)
            update(L, R, lson, val);
        if(R>m)
            update(L, R, rson, val);
        pushUp(rt);
    }
    int query(int L, int R, int l, int r, int rt) {
        if(L<=l&&R>=r) {
            return sum[rt];
        }
        pushDown(rt, r-l+1);
        int m = l+r>>1, ret = 0;
        if(L<=m)
            ret += query(L, R, lson);
        if(R>m)
            ret += query(L, R, rson);
        return ret;
    }
    int bin(int l, int r, int val) {
        int ans, pos = l;
        while(l<=r) {
            int m = l+r>>1;
            if(m-pos+1-query(pos, m, 1, n, 1)>=val) {
                r = m-1;
                ans = m;
            } else {
                l = m+1;
            }
        }
        return ans;
    }
    int main()
    {
        int t, m, x, y, sign;
        cin>>t;
        while(t--) {
            scanf("%d%d", &n, &m);
            mem1(cnt);
            mem(sum);
            while(m--) {
                scanf("%d%d%d", &sign, &x, &y);
                x++;
                if(sign == 1) {
                    int num = query(x, n, 1, n, 1);
                    if(num == n-x+1) {
                        puts("Can not put any one.");
                        continue;
                    }
                    y = min(y, n-x+1-num);
                    int l = bin(x, n, 1);
                    int r = bin(l, n, y);
                    printf("%d %d
    ", l-1, r-1);
                    update(l, r, 1, n, 1, 1);
                } else {
                    y++;
                    printf("%d
    ", query(x, y, 1, n, 1));
                    update(x, y, 1, n, 1, 0);
                }
            }
            cout<<endl;
        }
        return 0;
    }
  • 相关阅读:
    动画电影分享
    Nginx 学习
    震惊!一步激活idea,亲测有效-2020-7-9
    根据oracle判断语句结果,进行循环语句
    Oracle11g的exp导出空表提示EXP-00011: 不存在
    查询某个用户下各个表的数据量
    Oracle批量修改表字段类型(存储过程)
    PLS-00201: identifier 'SYS.DBMS_EXPORT_EXTENSION' must be declared
    Oracle AWR报告生成和大概分析
    oracle如何给原有的用户变更表空间
  • 原文地址:https://www.cnblogs.com/yohaha/p/5216081.html
Copyright © 2011-2022 走看看