#include
<
stdio.h
>
#define
maxn 50005
struct
{
/*
ml线段左边的最大空位,mr线段右边的最大空位,mm线段的最大空位,f线段最大空位的起始位置
cov线段是否被覆盖,ud线段被覆盖时,有没有往下将更改传递给孩子,len线段的长度
*/
int
l, r, ml, mr, mm, f, cov, ud, len;
}tree[maxn
*
3
];
void
build (
int
l,
int
r,
int
i)
{
tree[i].l
=
l, tree[i].r
=
r;
tree[i].ml
=
tree[i].mr
=
tree[i].len
=
tree[i].mm
=
r
-
l
+
1
;
tree[i].f
=
tree[i].l;
tree[i].cov
=
tree[i].ud
=
0
;
if
(l
==
r)
{
return
;
}
int
m
=
(l
+
r)
/
2
;
build (l, m , i
*
2
), build (m
+
1
, r, i
*
2
+
1
);
}
void
down(
int
i)
{
/*
往下传递改节点的覆盖信息,如果往下传递,则更新孩子的数据
因为赖操作是针对已经确定被更新的线段的整块区域,所以不管孩子的在没修改之前的信息如何,都要被覆盖。孩子之前的信息已经没用了。
*/
if
(tree[i].ud)
//
tree[i].ud为1时,表示该节点的覆盖信息还没传递到孩子,否则,表示该节点的信息已经传递给孩子了
{
//
对自己的更改
if
(tree[i].cov)
{
tree[i].ml
=
tree[i].mr
=
tree[i].mm
=
0
;
}
else
{
tree[i].ml
=
tree[i].mr
=
tree[i].mm
=
tree[i].r
-
tree[i].l
+
1
;
tree[i].f
=
tree[i].l;
}
//
对孩子的更改,由于对于赖操作的更细传递到该节点,如果要利用到孩子节点的信息,所以也要修改孩子的数据
if
(tree[i].l
!=
tree[i].r)
{
tree[i
*
2
].cov
=
tree[i
*
2
+
1
].cov
=
tree[i].cov;
tree[i
*
2
].ud
=
tree[i
*
2
+
1
].ud
=
1
;
if
(tree[i].cov)
{
tree[i
*
2
].ml
=
tree[i
*
2
].mr
=
tree[i
*
2
].mm
=
0
;
tree[i
*
2
+
1
].ml
=
tree[i
*
2
+
1
].mr
=
tree[i
*
2
+
1
].mm
=
0
;
}
else
{
tree[i
*
2
].ml
=
tree[i
*
2
].mr
=
tree[i
*
2
].mm
=
tree[i
*
2
].r
-
tree[i
*
2
].l
+
1
;
tree[i
*
2
].f
=
tree[i
*
2
].l;
tree[i
*
2
+
1
].ml
=
tree[i
*
2
+
1
].mr
=
tree[i
*
2
+
1
].mm
=
tree[i
*
2
+
1
].r
-
tree[i
*
2
+
1
].l
+
1
;
tree[i
*
2
+
1
].f
=
tree[i
*
2
+
1
].l;
}
}
tree[i].ud
=
0
;
}
}
void
insert(
int
l,
int
r,
int
i,
int
cov)
{
if
(tree[i].l
>=
l
&&
tree[i].r
<=
r)
//
线段在更新范围内,则只需将修改信息传递给孩子,并修改必要的数据后直接返回
{
tree[i].cov
=
cov;
tree[i].ud
=
1
;
down(i);
return
;
}
down(i);
int
m
=
(tree[i].l
+
tree[i].r)
>>
1
;
if
(l
>
m)
{
insert(l, r, i
*
2
+
1
, cov);
}
else
if
(m
>=
r)
{
insert(l, r, i
*
2
, cov);
}
else
{
insert(l, r, i
*
2
, cov), insert(l, r, i
*
2
+
1
, cov);
}
//
由于改线段没被覆盖,数据的信息要通过孩子的信息来结合修改。
tree[i].ml
=
tree[i
*
2
].ml, tree[i].mr
=
tree[i
*
2
+
1
].mr;
if
(tree[i
*
2
].ml
==
tree[i
*
2
].len)
{
tree[i].ml
+=
tree[i
*
2
+
1
].ml;
}
if
(tree[i
*
2
+
1
].mr
==
tree[i
*
2
+
1
].len)
{
tree[i].mr
+=
tree[i
*
2
].mr;
}
tree[i].mm
=
tree[i
*
2
].mm;
tree[i].f
=
tree[i
*
2
].f;
if
(tree[i].mm
<
tree[i
*
2
].mr
+
tree[i
*
2
+
1
].ml)
{
tree[i].mm
=
tree[i
*
2
].mr
+
tree[i
*
2
+
1
].ml;
tree[i].f
=
tree[i
*
2
].r
-
tree[i
*
2
].mr
+
1
;
}
if
(tree[i].mm
<
tree[i
*
2
+
1
].mm)
{
tree[i].mm
=
tree[i
*
2
+
1
].mm;
tree[i].f
=
tree[i
*
2
+
1
].f;
}
}
int
find(
int
len,
int
i)
{
down(i);
if
(tree[i].ml
>=
len)
{
return
tree[i].l;
}
else
if
(tree[i
*
2
].mm
>=
len)
{
return
find (len, i
*
2
);
}
else
if
(tree[i
*
2
].mr
+
tree[i
*
2
+
1
].ml
>=
len)
{
return
tree[i
*
2
].r
-
tree[i
*
2
].mr
+
1
;
}
else
if
(tree[i
*
2
+
1
].mm
>=
len)
{
return
find (len, i
*
2
+
1
);
}
return
0
;
}
int
main()
{
int
n, m, op, d, x, ans;
scanf(
"
%d%d
"
,
&
n,
&
m);
build (
1
, n,
1
);
while
(m
--
)
{
scanf(
"
%d
"
,
&
op);
if
(op
==
1
)
{
scanf(
"
%d
"
,
&
d);
ans
=
find(d,
1
);
printf(
"
%d\n
"
, ans);
if
(ans)
{
insert(ans, ans
+
d
-
1
,
1
,
1
);
}
}
else
if
(op
==
2
)
{
scanf(
"
%d%d
"
,
&
x,
&
d);
insert(x, x
+
d
-
1
,
1
,
0
);
}
}
return
0
;
}