P2894 [USACO08FEB]酒店Hotel

来给大家扫一下雷吧.
做法大家看别人博客就好, 我说一下容易错的地方:

  1. 传标以后清标了吗?
  2. pushup函数(用左右子树的信息维护当前节点)写对了吗? 特别注意最长连续空房总数这个信息的维护.
  3. 初始化了吗?别忘了初始时都是空房, 节点信息不为0.
  4. 没有连续空房时输出0这个条件遗漏了吗?

假如你这些都注意了但还是错了, 那么这里给一组100规模的数据, 加油咯!~

https://files.cnblogs.com/files/wsmrxc/p2894.zip

#include <cstdio>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 5e4 + 10;
inline int read(){
    char ch = getchar(); int x = 0;
    while(!isdigit(ch)) ch = getchar();
    while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
    return x;
}

int N, M;

namespace stree
{
    #define mid ((l + r) >> 1)
    #define ls (o << 1)
    #define rs ((o << 1) | 1)

    struct Node
    {
        int cnt, llen, rlen, tag;
    }node[MAXN << 2];

    inline void pushup(int o, int l, int r) {
        if(mid - l + 1 == node[ls].cnt)
            node[o].llen = node[ls].llen + node[rs].llen;
        else node[o].llen = node[ls].llen;

        if(r - (mid + 1) + 1 == node[rs].cnt)
            node[o].rlen = node[ls].rlen + node[rs].rlen;
        else node[o].rlen = node[rs].rlen;

        node[o].cnt = max(node[ls].rlen + node[rs].llen, max(node[ls].cnt, node[rs].cnt));
    }

    inline void givetag(int o, int l, int r, int v) {
        if(v == 1) node[o].cnt = node[o].llen = node[o].rlen = 0;
        if(v == 2) node[o].cnt = node[o].llen = node[o].rlen = r - l + 1;
        node[o].tag = v;
    }

    inline void pushdown(int o, int l, int r) {
        int &v = node[o].tag; if(!v) return ;
        givetag(ls, l, mid, v), givetag(rs, mid + 1, r, v);
        v = 0;
    }

    void modify(int o, int l, int r, int a, int b, int v) {
        if(l > b || r < a) return ;
        if(a <= l && r <= b) return givetag(o, l, r, v);
        pushdown(o, l, r);
        modify(ls, l, mid, a, b, v), modify(rs, mid + 1, r, a, b, v);
        return pushup(o, l, r);
    }

    int query(int o, int l, int r, int len) {
        if(l == r) return l;
        if(node[o].cnt < len) return 0;
        pushdown(o, l, r);
        if(node[ls].cnt >= len) return query(ls, l, mid, len);
        if(node[ls].rlen + node[rs].llen >= len) 
            return mid - node[ls].rlen + 1;
        else return query(rs, mid + 1, r, len); 
    }
}

int main(){
    // freopen("p2894.in", "r", stdin);
    // freopen("p2894.out", "w", stdout);
    cin>>N>>M;
    stree::givetag(1, 1, N, 2);
    while(M--) {
        using namespace stree;
        int opt = read();
        if(opt == 1) {
            int x = read(), tmp = query(1, 1, N, x);
            printf("%d\n", tmp);
            if(tmp) modify(1, 1, N, tmp, tmp + x - 1, 1);
        }
        else {
            int x = read(), y = read();
            modify(1, 1, N, x, x + y - 1, 2);
        }
    }
    return 0;
}
posted @ 2018-10-26 10:31  俺是小程  阅读(210)  评论(0编辑  收藏  举报