P2894 [USACO08FEB]酒店Hotel
来给大家扫一下雷吧.
做法大家看别人博客就好, 我说一下容易错的地方:
- 传标以后清标了吗?
- pushup函数(用左右子树的信息维护当前节点)写对了吗? 特别注意
最长连续空房总数
这个信息的维护. - 初始化了吗?别忘了初始时都是空房, 节点信息不为0.
没有连续空房时输出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;
}