![BZOJ1593 [Usaco2008 Feb]Hotel 旅馆 BZOJ1593 [Usaco2008 Feb]Hotel 旅馆](https://image.shishitao.com:8440/aHR0cHM6Ly9ia3FzaW1nLmlrYWZhbi5jb20vdXBsb2FkL2NoYXRncHQtcy5wbmc%2FIQ%3D%3D.png?!?w=700&webp=1)
裸上线段树,就是记的东西有点多。。。
每个点记区间左端最长0,右端最长0,中间最长0,和tag表示是否全为0/1
直接更新就好,查询的时候先查左儿子,然后查中间,最后查右儿子。。。
/**************************************************************
Problem: 1593
User: rausen
Language: C++
Result: Accepted
Time:388 ms
Memory:4404 kb
****************************************************************/ #include <cstdio>
#include <algorithm> using namespace std; inline int read(); struct seg {
seg *ls, *rs;
int mxl, mxm, mxr, len, tag; #define Len (1 << 16)
void* operator new(size_t, int x) {
static seg *mempool, *c;
if (c == mempool)
mempool = (c = new seg[Len]) + Len;
c -> ls = c -> rs = NULL;
c -> mxl = c -> mxr = c -> mxm = c -> len = x, c -> tag = -;
return c++;
}
#undef Len #define mid (l + r >> 1)
#define Ls this -> ls
#define Rs this -> rs
inline void fill(int d) {
if (d) this -> mxl = this -> mxr = this -> mxm = ;
else this -> mxl = this -> mxr = this -> mxm = this -> len;
this -> tag = d;
} inline void push() {
if (~this -> tag) {
if (Ls) Ls -> fill(this -> tag);
if (Rs) Rs -> fill(this -> tag);
this -> tag = -;
}
}
inline void update() {
this -> mxl = Ls -> mxl + (Ls -> mxl == Ls -> len ? Rs -> mxl : );
this -> mxr = Rs -> mxr + (Rs -> mxr == Rs -> len ? Ls -> mxr : );
this -> mxm = max(max(Ls -> mxm, Rs -> mxm), Ls -> mxr + Rs -> mxl);
} void build(int l, int r) {
if (l == r) return;
Ls = new(mid - l + )seg, Ls -> build(l, mid);
Rs = new(r - mid)seg, Rs -> build(mid + , r);
} void modify(int l, int r, int L, int R, int d) {
if (L <= l && r <= R) {
this -> fill(d);
return;
}
this -> push();
if (L <= mid) Ls -> modify(l, mid, L, R, d);
if (mid < R) Rs -> modify(mid + , r, L, R, d);
this -> update();
} int query(int l, int r, int len) {
this -> push();
if (this -> mxm < len) return ;
if (Ls -> mxm >= len) return Ls -> query(l, mid, len);
if (Ls -> mxr + Rs -> mxl >= len) return mid - Ls -> mxr + ;
if (Rs -> mxm >= len) return Rs -> query(mid + , r, len);
}
#undef mid
#undef Ls
#undef Rs
} *segment; int n, m; int main() {
int i, oper, x, y;
n = read(), m = read();
segment = new(n)seg;
segment -> build(, n);
for (i = ; i <= m; ++i) {
oper = read();
if (oper == ) {
x = segment -> query(, n, y = read());
printf("%d\n", x);
if (x) segment -> modify(, n, x, x + y - , );
} else {
x = read(), y = read();
segment -> modify(, n, x, x + y - , );
}
}
return ;
} inline int read() {
static int x;
static char ch;
x = , ch = getchar();
while (ch < '' || '' < ch)
ch = getchar();
while ('' <= ch && ch <= '') {
x = x * + ch - '';
ch = getchar();
}
return x;
}