1 /*
2 建一颗线段树
3 储存四个信息 lm 代表从区间左端点开始向右连续最长为空的序列长度
4 rm 代表从区间右端点开始向左连续最长为空的序列长度
5 m 代表区间内连续最长为空的序列长度
6 s 代表区间长度
7 维护 前三个信息
8 用 s 判断区间是否可用 从而更新 lm rm 和 m
9 具体看操作
10 */
11 #include<cstdio>
12 #include<iostream>
13 #define MAXN 100010
14
15 using namespace std;
16
17 struct de {
18 int l,r;
19 int s,lm,rm,m;
20 int tag;
21 };
22 de tr[MAXN<<2];
23
24 int n,T,opt,x,y;
25
26 inline void read(int&x) {
27 int f=1;x=0;char c=getchar();
28 while(c>‘9‘||c<‘0‘) {if(c==‘-‘) f=-1;c=getchar();}
29 while(c>=‘0‘&&c<=‘9‘) {x=(x<<1)+(x<<3)+c-48;c=getchar();}
30 x=x*f;
31 }
32
33 inline void up(int now) {
34 if(tr[now<<1].m==tr[now<<1].s) tr[now].lm=tr[now<<1].m+tr[now*2+1].lm;
35 else tr[now].lm=tr[now<<1].lm;
36 if(tr[now*2+1].m==tr[now*2+1].s) tr[now].rm=tr[now*2+1].m+tr[now<<1].rm;
37 else tr[now].rm=tr[now*2+1].rm;
38 tr[now].m=max(max(tr[now<<1].m,tr[now*2+1].m),tr[now<<1].rm+tr[now*2+1].lm);
39 return;
40 }
41
42 inline void down(int now) {
43 if(tr[now].tag==1) {
44 tr[now<<1].tag=tr[now*2+1].tag=tr[now].tag;
45 tr[now<<1].lm=tr[now<<1].rm=tr[now<<1].m=0;
46 tr[now*2+1].lm=tr[now*2+1].m=tr[now*2+1].rm=0;
47 }
48 if(tr[now].tag==2) {
49 tr[now<<1].tag=tr[now*2+1].tag=tr[now].tag;
50 tr[now<<1].lm=tr[now<<1].rm=tr[now<<1].m=tr[now<<1].s;
51 tr[now*2+1].lm=tr[now*2+1].m=tr[now*2+1].rm=tr[now*2+1].s;
52 }
53 tr[now].tag=0;
54 }
55
56 void build_tree(int now,int l,int r) {
57 tr[now].l=l;tr[now].r=r;
58 tr[now].lm=tr[now].rm=tr[now].m=tr[now].s=r-l+1;
59 if(l==r) return;
60 int mid=(l+r)>>1;
61 build_tree(now<<1,l,mid);
62 build_tree(now*2+1,mid+1,r);
63 return;
64 }
65
66 int query(int now,int l,int r,int len) {
67 if(tr[now].l==tr[now].r) return l;
68 if(tr[now].tag) down(now);
69 int mid=(tr[now].l+tr[now].r)>>1;
70 if(tr[now<<1].m>=len) return query(now<<1,l,r,len);
71 if(tr[now<<1].rm+tr[now*2+1].lm>=len) return mid-tr[now<<1].rm+1;
72 else return query(now*2+1,mid+1,r,len);
73 }
74
75 void modify(int now,int l,int r,int d) {
76 if(l<=tr[now].l&&r>=tr[now].r) {
77 if(d==1) tr[now].lm=tr[now].rm=tr[now].m=0;
78 else tr[now].lm=tr[now].rm=tr[now].m=tr[now].s;
79 tr[now].tag=d;
80 return;
81 }
82 if(tr[now].tag) down(now);
83 int mid=(tr[now].l+tr[now].r)>>1;
84 if(l<=mid) modify(now<<1,l,r,d);
85 if(r>mid) modify(now*2+1,l,r,d);
86 up(now);
87 }
88
89 int main() {
90 read(n);read(T);
91 build_tree(1,1,n);
92 while(T--) {
93 read(opt);
94 if(opt==1) {
95 read(x);
96 if(tr[1].m<x) {printf("0\n");continue;}
97 int pos=query(1,1,n,x);
98 printf("%d\n",pos);
99 modify(1,pos,pos+x-1,1);
100 }
101 else {
102 read(x);read(y);
103 modify(1,x,y+x-1,2);
104 }
105 }
106 return 0;
107 }