HDU 4614 Vases and Flowers——线段树+二分

来源:互联网 发布:淘宝怎么让宝贝排名靠前 编辑:程序博客网 时间:2024/06/06 19:41

线段树就是最普通的线段树,二分比较恶心,先二分上界。找到第一个出现的0(这个有技巧,参考代码),二分下界,找到第一个区间0的数量等于k的位置(类似lower_bound)

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 5 * 1e4 + 10;int T, n, m;struct SegTree {    int sum[maxn<<2], lazy[maxn<<2];    void pushup(int root) { sum[root] = sum[root<<1] + sum[root<<1|1]; }    void pushdown(int root, int L, int mid, int R) {        if (lazy[root] == -1) return;        int cntL = mid - L + 1, cntR = R - mid;        lazy[root<<1] = lazy[root<<1|1] = lazy[root];        sum[root<<1] = lazy[root] * cntL; sum[root<<1|1] = lazy[root] * cntR;        lazy[root] = -1;    }    void build() {        memset(sum, 0, sizeof(sum)); memset(lazy, -1, sizeof(lazy));    }    void update(int L, int R, int root, int uL, int uR, int val) {        if (uL <= L && R <= uR) {            lazy[root] = val;            sum[root] = val * (R - L + 1);            return;        }        int mid = (L + R)>>1;        pushdown(root, L, mid, R);        if (uL <= mid) update(L, mid, root<<1, uL, uR, val);        if (mid < uR) update(mid + 1, R, root<<1|1, uL, uR, val);        pushup(root);    }    int query(int L, int R, int root, int qL, int qR) {        if (qL <= L && R <= qR) return sum[root];        int mid = (L + R)>>1;        pushdown(root, L, mid, R);        int sum = 0;        if (qL <= mid) sum += query(L, mid, root<<1, qL, qR);        if (mid < qR) sum += query(mid + 1, R, root<<1|1, qL, qR);        return sum;    }}segtree;int main() {    scanf("%d", &T);    while(T--) {        scanf("%d %d", &n, &m);        segtree.build();        while (m--) {            int k, x, y; scanf("%d %d %d", &k, &x, &y);            if (k == 1) {                int sum = segtree.query(1, n, 1, x + 1, n), L, R, mid;                if (sum == n - x) { printf("Can not put any one.\n"); continue; }                y = min(y, n - x - sum);                L = x + 1, R = n;                while (L < R) {                    mid = (L + R)>>1;                    if (segtree.query(1, n, 1, x + 1, mid) == mid - x) L = mid + 1;                    else R = mid;                }                printf("%d ", L - 1);                L = x + 1, R = n;                while (L < R) {                    mid = (L + R)>>1;                    if (mid - x - segtree.query(1, n, 1, x + 1, mid) >= y) R = mid;                    else L = mid + 1;                }                printf("%d\n", R - 1);                segtree.update(1, n, 1, x + 1, R, 1);            }            else {                printf("%d\n", segtree.query(1, n, 1, x+1, y+1));                segtree.update(1, n, 1, x+1, y+1, 0);            }        }        printf("\n");    }    return 0;}