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

    题目大意:有编号为[0,N-1]的花盆,有下述2种操作:

    1 A F,有F朵花,从A开始放入花盆,(最后放不下的丢弃)

    2 A B,清理[A,B]花盆里的花。

    对每种操作:对1输出第一个和最后一个放入花的花盆编号,无位置时输出“Can not put any one.”

    对2输出清理掉的花盆数量。

    对2操作,就是一个简单的线段树区间和的查询,不提先。

    对于1操作,相当要找到[A, N-1]花盆中第k个空盆。一开始想的时候,线段树结点T[rt]表示的是这个区间花的数量,这样来求第k个空盆比较麻烦,后面转成想:T[rt]表示的是这个区间空盆数量,再找的时候就如同query2写的,非常流畅了。另:第k个空盆,这个k得在剩余空盆和实际要插的花朵数量之间取min。

    
    #include <stdio.h>
    #include <iostream>
    #include <string.h>
    using namespace std;
    
    #define ll long long
    #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
    #define DOR(i,a,b) for(int i=(a);i>=(b);--i)
    
    const int maxN=5e4+5,inf=0x3f3f3f3f;
    int N, M, K, T[maxN<<2], Z[maxN<<2];
    
    #define lson l,m,rt*2
    #define rson m+1,r,rt*2+1
    
    void push_up(int rt) {T[rt] = T[rt * 2] + T[rt * 2 + 1];}
    void push_down(int l, int r, int rt) {
        if (Z[rt] == -1) return;
        int lch = rt * 2, rch = lch + 1;
        Z[lch] = Z[rch] = Z[rt];
        int LE = r - l + 1;
        T[lch] = (LE - LE / 2) * Z[rt];
        T[rch] = (LE / 2) * Z[rt];
        Z[rt] = -1;
    }
    void build(int l, int r, int rt) {
        Z[rt] = -1;
        T[rt] = (r - l + 1);
        if (l == r) return;
        int m = (l + r) / 2;
        build(lson), build(rson);
        push_up(rt);
    }
    void update(int L, int R, int x, int l, int r, int rt) {
        if (L <= l && r <= R) {
            Z[rt] = x;
            T[rt] = (r - l + 1) * x;
            return;
        }
        push_down(l, r, rt);
        int m = (l + r) / 2;
        if (L <= m) update(L, R, x, lson);
        if (R > m) update(L, R, x, rson);
        push_up(rt);
    }
    int query1(int L, int R, int l, int r, int rt) {
        if (L <= l && r <= R) return T[rt];
        push_down(l, r, rt);
        int m = (l + r) / 2;
        int ans = 0;
        if (L <= m) ans += query1(L, R, lson);
        if (R > m) ans += query1(L, R, rson);
        // push_up(rt);
        return ans;
    }
    int query2(int L, int R, int k, int l, int r, int rt) {
        if (l == r) return l;
        push_down(l, r, rt);
        int m = (l + r) / 2;
        int cnt = query1(L, m, l, r, rt);
        if (cnt >= k) return query2(L, R, k, lson);
        else return query2(L, R, k - cnt, rson);
    }
    
    int main () {
        int cas;
        scanf("%d", &cas);
        FOR(ca, 1, cas) {
            scanf("%d%d", &N, &M);
            build(0, N - 1, 1);
            int op, a, b;
            FOR(j, 1, M) {
                scanf("%d%d%d", &op, &a, &b);
                if (op == 2) {
                    int q = query1(a, b, 0, N - 1, 1);
                    printf("%d
    ", b - a + 1 - q);
                    update(a, b, 1, 0, N - 1, 1);
                } else {
                    if (query1(a, N - 1, 0, N - 1, 1) == 0) {
                        puts("Can not put any one.");
                        continue;
                    }
                    int empty = query1(a, N - 1, 0, N - 1, 1);
                    int x = query2(a, N - 1, 1, 0, N - 1, 1);
                    int y = query2(a, N - 1, min(b, empty), 0, N - 1, 1);
                    printf("%d %d
    ", x, y);
                    update(x, y, 0, 0, N - 1, 1);
                }
            }
            puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    ArcMap+ArcCatalog手工新建点层及添加数据
    zedGraph 图表控件总结(一)
    Android 开发学习笔记(五)—— 最简单的注册界面
    repeater实现删除按钮
    repeater分页实例
    FCKeditor的使用说明
    javascript:void(0)是什么意思
    为asp.net控件点击事件添加Confirm()
    LINQ判断素数
    U盘文件不能删除,怎么处理
  • 原文地址:https://www.cnblogs.com/Rosebud/p/9689518.html
Copyright © 2011-2022 走看看