题目大意:
旅店有N个房间,排成一排,房间编号为1~N。有三种类型的操作:
第1种,输入i和M。表示i ~ i + M - 1这段房间入住旅客。
第2中,输入i和M。表示i ~ i + M - 1这段房间离开旅客。
第3中,需要输出最多的连续的空房间。
有P次操作。3 <= N <= 16000,3 <= P <= 200000。解题思路:
典型的线段树。关键是怎样去维护最大的连续的。设一个节点最大的连续的空房间为max_len,从左边起连续的空房间为l_c,从右边起连续的空房间为r_c。那么合并两个区间的时候,就要考虑合并之后可能会形成一段新的连续的空房间。还有就是在更新l_c和r_c的时候也是需要注意的。代码一看就懂,有什么写得不好的地方请多指教!Show me the code!
#include <cstdio>
#define mid l + (r - l) / 2
#define lson id << 1, l, mid
#define rson id << 1 | 1, mid + 1, r
using namespace std;
const int MAXN = 16001;
class Node{
public:
int max_len, l_c, r_c;
Node(){
}
Node(int max_len, int l_c, int r_c) {
this->max_len = max_len;
this->l_c = l_c;
this->r_c = r_c;
}
}tree[MAXN * 4];
int laze[MAXN * 4];
int max(int a, int b, int c) {
a = a > b ? a : b;
a = a > c ? a : c;
return a;
}
Node max(int id1, int l1, int r1, int id2, int l2, int r2) {
Node res;
res.max_len = max(tree[id1].max_len, tree[id2].max_len, tree[id1].r_c + tree[id2].l_c);
if (tree[id1].l_c == r1 - l1 + 1) res.l_c = tree[id1].l_c + tree[id2].l_c;
else res.l_c = tree[id1].l_c;
if (tree[id2].r_c == r2 - l2 + 1) res.r_c = tree[id2].r_c + tree[id1].r_c;
else res.r_c = tree[id2].r_c;
return res;
}
void build(int id, int l, int r) {
laze[id] = -1;
if (l == r) tree[id] = Node(1, 1, 1);
else {
build(lson);
build(rson);
tree[id] = max(lson, rson);
}
}
void pushdown(int id, int l, int r) {
if (laze[id] == 1) {
tree[id << 1] = Node(0, 0, 0);
laze[id << 1] = 1;
tree[id << 1 | 1] = Node(0, 0, 0);
laze[id << 1 | 1] = 1;
}
else {
int t_l = l, t_r = mid;
int d = t_r - t_l + 1;
tree[id << 1] = Node(d, d, d);
laze[id << 1] = 0;
t_l = mid + 1, t_r = r;
d = t_r - t_l + 1;
tree[id << 1 | 1] = Node(d, d, d);
laze[id << 1 | 1] = 0;
}
laze[id] = -1;
}
void updata(int id, int l, int r, int L, int R, int flag) {
if (R < l || r < L) return;
if (L <= l && r <= R) {
if (flag == 1) {
tree[id] = Node(0, 0, 0);
laze[id] = 1;
}
else {
tree[id] = Node(r - l + 1, r - l + 1, r - l + 1);
laze[id] = 0;
}
return;
}
if (laze[id] != -1) pushdown(id, l, r);
updata(lson, L, R, flag);
updata(rson, L, R, flag);
tree[id] = max(lson, rson);
}
int main() {
int N, P;
scanf("%d%d", &N, &P);
build(1, 1, N);
for (int a = 0; a < P; ++a) {
int op;
scanf("%d", &op);
if (op == 3) {
printf("%d\n", tree[1].max_len);
}
else {
int a, b;
scanf("%d%d", &a, &b);
if (op == 1) updata(1, 1, N, a, a + b - 1, 1);
else updata(1, 1, N, a, a + b - 1, 0);
}
}
return 0;
}