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;
    }
  • 相关阅读:
    获取URL中参数
    Javascript this指针
    10分钟了解C#中的协变和逆变
    BCB写的简单的EXCEL合并
    Codeforces Round #316 (Div. 2) D
    Codeforces Round #316 (Div. 2) E
    fzu1873 Coin Puzzle
    hdu 3629 Convex
    几何统计 ACM ICPC
    hdu 5135 Little Zu Chongzhi's Triangles
  • 原文地址:https://www.cnblogs.com/yohaha/p/5216081.html
Copyright © 2011-2022 走看看