刚看感觉好难的样子,试着写了写,用一个半小时A掉了
发现有时候自己A掉某个题的实力还是有的,但总是对自己没有信心。。。导致连试都不敢试
这个题其实真的没有那么难
题意是:
又一段连续的空房子,现在有如下三种操作
1、从x处开始,连续y间房子入住
2、从x处开始,连续y间房子清空
3、查询当前最大连续空房子
我们在线段树中记录每段区间的左侧连续空房间数、右侧连续空房间数和这段区间内最大连续空房间数
那么就很容易做了
注意状态的转移
3469ms代码如下:
#include <cstdio>
#include <iostream>
#include <algorithm>
#define MAXN 18010
using namespace std;
struct NODE {
int left, right;
int length, lazy;
}node[MAXN<<2];
void PushUp(int l, int r, int rt) {
int tmp = node[rt<<1].right+node[rt<<1|1].left;
node[rt].length = max(node[rt<<1].left, node[rt<<1|1].right);
node[rt].length = max(node[rt].length, tmp);
node[rt].length = max(node[rt].length, node[rt<<1].length);
node[rt].length = max(node[rt].length, node[rt<<1|1].length);
int m = (l+r)>>1;
if(node[rt<<1].left == m-l+1 && node[rt<<1].left)//刚开始这里写出了一个bug,开始判断的是left==right,这是不对的,两者相等不等价于这段区间是空的
node[rt].left = node[rt<<1].right + node[rt<<1|1].left;
else node[rt].left = node[rt<<1].left;
if(node[rt<<1|1].left == r-m && node[rt<<1|1].left)
node[rt].right = node[rt<<1].right + node[rt<<1|1].left;
else node[rt].right = node[rt<<1|1].right;
}
void PushDown(int l, int r, int rt) {
int tmp = node[rt].lazy;
int m = (l+r)>>1;
if(tmp != 0) {
node[rt<<1].lazy = node[rt<<1|1].lazy = tmp;
if(tmp == 1) {
tmp = m-l+1;
node[rt<<1].length = tmp;
node[rt<<1].left = tmp;
node[rt<<1].right = tmp;
tmp = r-m;
node[rt<<1|1].length = tmp;
node[rt<<1|1].left = tmp;
node[rt<<1|1].right = tmp;
} else {
node[rt<<1].left = node[rt<<1].right = 0;
node[rt<<1].length = 0;
node[rt<<1|1].left = node[rt<<1|1].right = 0;
node[rt<<1|1].length = 0;
}
node[rt].lazy = 0;
}
}
void build(int l, int r, int rt) {
node[rt].lazy = 0;
if(l == r) {
node[rt].length = 1;
node[rt].left = node[rt].right = 1;
return ;
}
int m = (l+r)>>1;
build(l, m, rt<<1);
build(m+1, r, rt<<1|1);
PushUp(l, r, rt);
//printf("node[%d]: left=%d\tright=%d\tlength=%d\n", rt, node[rt].left, node[rt].right, node[rt].length);
}
void update(int L, int R, int add, int l, int r, int rt) {
if(L<=l && r<=R) {
node[rt].lazy = add;
if(add == -1) {
node[rt].left = 0;
node[rt].right = 0;
node[rt].length = 0;
} else {
node[rt].left = r-l+1;
node[rt].right = r-l+1;
node[rt].length = r-l+1;
}
return ;
}
PushDown(l, r, rt);
int m = (l+r)>>1;
if(L <= m) {
update(L, R, add, l, m, rt<<1);
//printf("update(%d, %d, %d, %d, %d, %d)\n", L, R, add, l, m, rt<<1);
}
if(R > m) {
update(L, R, add, m+1, r, rt<<1|1);
//printf("update(%d, %d, %d, %d, %d, %d)\n", L, R, add, m+1, r, rt<<1|1);
}
PushUp(l, r, rt);
}
void show(int l, int r, int rt) {
if(l == r) {
printf("node[%d]: left=%d\tright=%d\tlength=%d\n", rt, node[rt].left, node[rt].right, node[rt].length);
return ;
}
int m = (l+r)>>1;
show(l, m, rt<<1);
show(m+1, r, rt<<1|1);
printf("node[%d]: left=%d\tright=%d\tlength=%d\n", rt, node[rt].left, node[rt].right, node[rt].length);
}
int main(void) {
int n, p, x, y, type;
while(~scanf("%d%d", &n, &p)) {
build(1, n, 1);
while(p--) {
scanf("%d", &type);
if(type == 1) {
scanf("%d%d", &x, &y);//从x处开始y人入住
update(x, x+y-1, -1, 1, n, 1);
//show(1, n, 1);
} else if(type == 2) {
scanf("%d%d", &x, &y);//从x处开始y人离开
update(x, x+y-1, 1, 1, n, 1);
//show(1, n, 1);
} else {
printf("%d\n", node[1].length);
}
}
}
return 0;
}