题意:
一个Hotel有N个房间,一开始全部为空。
接下来有M个询问。
输入1,代表房间被占用,然后输入两个数代表房间被占用的房间号和数量。
输入2,代表房间被置空,输入两个数代表房间被清空的房间号和数量。
输入3,输出连续最长没有被占用的房间数量。
思路:
线段树的区间更新,维护的值还是很好想的,
分别是当前
线段的maxl最长连续的左区间,maxr最长连续右区间,maxv最大值。
但是懒惰标记不好想,调试了很久都没有结果,后来参考了一段别人的代码,加上自己的理解,终于A了。
懒惰标记上面有3个值 0表示空,1表示满,-1表示非满非空。
然后根据这3个标记维护线段树。
my code
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ls (o<<1)
#define rs (o<<1|1)
using namespace std;
const int N = 16005;
struct Node {
int maxl, maxr, maxv;
int cover; //0表示空,1表示满,-1表示非满非空
void calc(int L, int R) {
if(cover == 1) //如果满,全部置为0
maxl = maxr = maxv = 0;
else if(cover == 0) //如果空,最长长度=区间长度
maxl = maxr = maxv = (R-L+1);
}
} node[N<<2];
void pushUp(int o, int L, int R) {
int M = (L+R)/2;
int lenL = (M-L+1), lenR = (R-M);
if(node[ls].maxl == lenL) node[o].maxl = node[ls].maxv + node[rs].maxl;
else node[o].maxl = node[ls].maxl;
if(node[rs].maxr == lenR) node[o].maxr = node[rs].maxv + node[ls].maxr;
else node[o].maxr = node[rs].maxr;
node[o].maxv = (node[ls].maxr + node[rs].maxl);
node[o].maxv = max(node[o].maxv, max(node[ls].maxv, node[rs].maxv));
if(node[ls].cover == node[rs].cover)
node[o].cover = node[ls].cover;
else
node[o].cover = -1;
}
void pushDown(int o, int L, int R) {
if(node[o].cover == -1) return;
node[ls].cover = node[rs].cover = node[o].cover;
node[o].cover = -1;
int M = (L+R)/2;
node[ls].calc(L, M);
node[rs].calc(M+1, R);
}
void build(int o, int L, int R) {
if(L == R) {
node[o].cover = 0;
node[o].calc(L, R);
return ;
}
int M = (L+R)/2;
build(ls, L, M);
build(rs, M+1, R);
pushUp(o, L, R);
}
int ql, qr, op;
void modify(int o, int L, int R) {
if(ql <= L && R <= qr) {
if(op == 1) node[o].cover = 1;
else node[o].cover = 0;
node[o].calc(L, R);
return ;
}
pushDown(o, L, R);
int M = (L+R)/2;
if(ql <= M) modify(ls, L, M);
if(qr > M) modify(rs, M+1, R);
pushUp(o, L, R);
}
int n, m;
int main() {
//freopen("in.txt", "r", stdin);
while(scanf("%d%d", &n, &m) != EOF) {
build(1, 1, n);
int x, y;
while(m--) {
scanf("%d", &op);
if(op == 1 || op == 2) {
scanf("%d%d", &x, &y);
ql = x, qr = x+y-1;
modify(1, 1, n);
}else {
printf("%d\n", node[1].maxv);
}
}
}
return 0;
}