线段树+模拟
空房间标记为1,已入住房间标记为0,这种表示便于统计某段区间内的连续空段长度
#include
<
iostream
>
#include
<
algorithm
>
using
namespace
std;
#define
MAXN 160010
#define
Max(a,b) (a>b?a:b)
int
n,p;
struct
Node{
int
l,r,
mx,
//
最大空段长度
lmx,
//
从区间左端开始的空段的最大长度
rmx;
//
bool
flag1,
//
true表示该段全为1(即该段全为空)
flag0;
//
true表示该段全为0(该段无空位)
}nod[
3
*
MAXN];
void
build(
int
u,
int
l,
int
r){
nod[u].flag1
=
true
;
nod[u].flag0
=
false
;
nod[u].l
=
l;
nod[u].r
=
r;
nod[u].lmx
=
nod[u].rmx
=
nod[u].mx
=
r
-
l
+
1
;
if
(l
==
r)
return
;
build(
2
*
u,l,(l
+
r)
/
2
);
build(
2
*
u
+
1
,(l
+
r)
/
2
+
1
,r);
}
void
checkin(
int
u,
int
l,
int
r){
//
将父亲信息继承给左右儿子
//
*
if
(nod[u].flag1){
nod[u].flag1
=
false
;
nod[
2
*
u].flag1
=
true
;
nod[
2
*
u].flag0
=
false
;
nod[
2
*
u].mx
=
nod[
2
*
u].lmx
=
nod[
2
*
u].rmx
=
nod[
2
*
u].r
-
nod[
2
*
u].l
+
1
;
nod[
2
*
u
+
1
].flag1
=
true
;
nod[
2
*
u
+
1
].flag0
=
false
;
nod[
2
*
u
+
1
].mx
=
nod[
2
*
u
+
1
].lmx
=
nod[
2
*
u
+
1
].rmx
=
nod[
2
*
u
+
1
].r
-
nod[
2
*
u
+
1
].l
+
1
;
}
if
(l
<=
nod[u].l
&&
nod[u].r
<=
r){
nod[u].lmx
=
nod[u].rmx
=
nod[u].mx
=
0
;
nod[u].flag0
=
true
;
return
;
}
if
(l
<=
nod[
2
*
u].r)
checkin(
2
*
u,l,r);
if
(nod[
2
*
u
+
1
].l
<=
r)
checkin(
2
*
u
+
1
,l,r);
//
由左右儿子更新维护父亲
//
*
nod[u].mx
=
Max(nod[
2
*
u].mx,nod[
2
*
u
+
1
].mx);
nod[u].mx
=
Max(nod[u].mx,nod[
2
*
u].rmx
+
nod[
2
*
u
+
1
].lmx);
if
(nod[
2
*
u].lmx
==
nod[
2
*
u].r
-
nod[
2
*
u].l
+
1
)
nod[u].lmx
=
nod[
2
*
u].lmx
+
nod[
2
*
u
+
1
].lmx;
else
nod[u].lmx
=
nod[
2
*
u].lmx;
if
(nod[
2
*
u
+
1
].rmx
==
nod[
2
*
u
+
1
].r
-
nod[
2
*
u
+
1
].l
+
1
)
nod[u].rmx
=
nod[
2
*
u
+
1
].rmx
+
nod[
2
*
u].rmx;
else
nod[u].rmx
=
nod[
2
*
u
+
1
].rmx;
if
(nod[u].mx
==
0
)
nod[u].flag0
=
true
;
}
void
checkout(
int
u,
int
l,
int
r){
if
(nod[u].flag0){
nod[u].flag0
=
false
;
nod[
2
*
u].flag0
=
true
;
nod[
2
*
u].flag1
=
false
;
nod[
2
*
u].mx
=
nod[
2
*
u].lmx
=
nod[
2
*
u].rmx
=
0
;
nod[
2
*
u
+
1
].flag0
=
true
;
nod[
2
*
u
+
1
].flag1
=
false
;
nod[
2
*
u
+
1
].mx
=
nod[
2
*
u
+
1
].lmx
=
nod[
2
*
u
+
1
].rmx
=
0
;
}
if
(l
<=
nod[u].l
&&
nod[u].r
<=
r){
nod[u].lmx
=
nod[u].rmx
=
nod[u].mx
=
nod[u].r
-
nod[u].l
+
1
;
nod[u].flag1
=
true
;
return
;
}
if
(l
<=
nod[
2
*
u].r)
checkout(
2
*
u,l,r);
if
(nod[
2
*
u
+
1
].l
<=
r)
checkout(
2
*
u
+
1
,l,r);
nod[u].mx
=
Max(nod[
2
*
u].mx,nod[
2
*
u
+
1
].mx);
nod[u].mx
=
Max(nod[u].mx,nod[
2
*
u].rmx
+
nod[
2
*
u
+
1
].lmx);
if
(nod[
2
*
u].lmx
==
nod[
2
*
u].r
-
nod[
2
*
u].l
+
1
)
nod[u].lmx
=
nod[
2
*
u].lmx
+
nod[
2
*
u
+
1
].lmx;
else
nod[u].lmx
=
nod[
2
*
u].lmx;
if
(nod[
2
*
u
+
1
].rmx
==
nod[
2
*
u
+
1
].r
-
nod[
2
*
u
+
1
].l
+
1
)
nod[u].rmx
=
nod[
2
*
u
+
1
].rmx
+
nod[
2
*
u].rmx;
else
nod[u].rmx
=
nod[
2
*
u
+
1
].rmx;
if
(nod[u].mx
==
nod[u].r
-
nod[u].l
+
1
)
nod[u].flag1
=
true
;
}
int
main(){
int
c,l,r;
while
(scanf(
"
%d%d
"
,
&
n,
&
p)
!=
EOF){
build(
1
,
1
,n);
while
(p
--
){
scanf(
"
%d
"
,
&
c);
if
(c
==
1
){
scanf(
"
%d%d
"
,
&
l,
&
r);
checkin(
1
,l,l
+
r
-
1
);
}
else
if
(c
==
2
){
scanf(
"
%d%d
"
,
&
l,
&
r);
checkout(
1
,l,l
+
r
-
1
);
}
else
printf(
"
%d\n
"
,nod[
1
].mx);
}
}
return
0
;
}