#include <bits/stdc++.h>
#define maxn 400005
using namespace std;
int n, m, tag[maxn];
struct node {
int sum, left, right, middle;
}ansn[maxn << 1];
int ls(int p) {
return p << 1;
}
int rs(int p) {
return p << 1 | 1;
}
void f(int p, int l, int r, int k) {
if(k) ansn[p].left = ansn[p].right = ansn[p].middle = 0;
if(!k) ansn[p].left = ansn[p].right = ansn[p].middle = (r - l + 1);
ansn[p].sum = k * (r - l + 1);
tag[p] = k;
}
void pushdown(int p, int l, int r) {
if(tag[p] == -1) return;
int mid = (l + r) >> 1;
f(ls(p), l, mid, tag[p]);
f(rs(p), mid + 1, r, tag[p]);
tag[p] = -1;
}
void pushup(int p, int l, int r) {
int mid = (l + r) >> 1;
ansn[p].sum = ansn[ls(p)].sum + ansn[rs(p)].sum;
if(ansn[ls(p)].left == mid - l + 1) ansn[p].left = mid - l + 1 + ansn[rs(p)].left;
else ansn[p].left = ansn[ls(p)].left;
if(ansn[rs(p)].right == r - mid) ansn[p].right = r - mid + ansn[ls(p)].right;
else ansn[p].right = ansn[rs(p)].right;
ansn[p].middle = max(max(ansn[ls(p)].middle, ansn[rs(p)].middle), ansn[ls(p)].right + ansn[rs(p)].left);
}
void update(int p, int l, int r, int nl, int nr, int k) {
pushdown(p, l, r);
if(nl <= l && r <= nr) {
if(k) ansn[p].left = ansn[p].right = ansn[p].middle = 0;
else if(!k) ansn[p].left = ansn[p].right = ansn[p].middle = r - l + 1;
ansn[p].sum = k * (r - l + 1);
tag[p] = k;
return;
}
int mid = (l + r) >> 1;
if(nl <= mid) update(ls(p), l, mid, nl, nr, k);
if(nr > mid) update(rs(p), mid + 1, r, nl, nr, k);
pushup(p, l, r);
}
//int query(int p, int l, int r, int x) {
// int mid = (l + r) >> 1;
// pushdown(p, l, r);
// if(ansn[p].left >= x) return l;
// if(ansn[p].middle >= x) {
// int res = query(ls(p), l, mid, x);
// if(res) return res;
// if(ansn[ls(p)].right + ansn[rs(p)].left >= x) return (mid - ansn[ls(p)].right + 1);
// res = query(rs(p), mid + 1, r, x);
// if(res) return res;
// }
// if(ansn[p].right >= x) return (r - x + 1);
// return 0;
//}
int query(int l, int r, int len, int x) {
pushdown(x, l, r);
if (l == r) return l;
int mid = (l + r) >> 1;
if (max(ansn[ls(x)].left, max(ansn[ls(x)].right, ansn[ls(x)].middle)) >= len) return query(l, mid, len, ls(x));
if (ansn[ls(x)].right + ansn[rs(x)].left >= len) return mid - ansn[ls(x)].right + 1;
else return query(mid + 1, r, len, rs(x));
}
void build(int p, int l, int r) {
if(l == r) {
ansn[p].left = ansn[p].right = ansn[p].middle = 1;
return;
}
int mid = (l + r) >> 1;
build(ls(p), l, mid);
build(rs(p), mid + 1, r);
pushup(p, l, r);
}
int main() {
scanf("%d%d", &n, &m);
memset(tag, -1, sizeof(tag));
build(1, 1, n);
for(int i = 1;i <= m;i++) {
int op, x, y;
scanf("%d", &op);
if(op == 1) {
scanf("%d", &x);
if(max(ansn[1].left, max(ansn[1].right, ansn[1].middle)) >= x) {
int res = query(1, n, x, 1);
printf("%d\n", res);
update(1, 1, n, res, res + x - 1, 1);
}
else puts("0");
}
else {
scanf("%d%d", &x, &y);
update(1, 1, n, x, x + y - 1, 0);
}
}
}
代码中注释掉的query只能拿16分, 这两个query除了读入顺序有什么不同吗(这份代码AC了)