• 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;
    }
  • 相关阅读:
    docker常用命令
    2020/10/10,饮食男女-对教条主义的补充和现实的摸索
    2020/08/24,约束力
    2020/08/21,迷茫的时候就去工作
    2020/08/21,神秘和平易近人
    2020/08/21,圣人和教条
    2020/07/21,翡翠梦境
    2020/10/10,生活不是阶段式跳跃的,是螺旋式的。
    2020/07/23,再论point,way,moment,time
    2020/07/13,旅游的意义是什么
  • 原文地址:https://www.cnblogs.com/yohaha/p/5216081.html
Copyright © 2020-2023  润新知