解题报告 『[SHOI2015]脑洞治疗仪（ODT）』

```#include <bits/stdc++.h>
using namespace std;
#define int long long
#define IT set<node>::iterator
#define rep(i, a, b) for (register int i = (a); i <= (b); i++)

int n, m;

struct node {
int l, r;
mutable int v;
node(int L, int R = -1, int V = 0): l(L), r(R), v(V) {}
int operator <(const node &o) const {
return l < o.l;
}
};

set<node> s;

int MAX(int a, int b) {return a > b ? a : b;}

int x = 0, flag = 0;
char ch = ' ';
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') {
flag = 1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ '0');
ch = getchar();
}
return flag ? -x : x;
}

IT split(int pos) {
IT it = s.lower_bound(node(pos));
if (it != s.end() && it->l == pos) return it;
it--;
int L = it->l, R = it->r, V = it->v;
s.erase(it);
s.insert(node(L, pos - 1, V));
return s.insert(node(pos, R, V)).first;
}

void assign(int l, int r, int val) {
IT itr = split(r + 1), itl = split(l);
s.erase(itl, itr);
s.insert(node(l, r, val));
}

int sum(int l, int r) {
IT itr = split(r + 1), itl = split(l);
int ans = 0;
while (itl != itr) {
ans += itl->v ? itl->r - itl->l + 1 : 0;
itl++;
}
return ans;
}

void repair(int l, int r, int num) {
IT itr = split(r + 1), itl = split(l);
while (itl != itr) {
if (!num) return;
if (!(itl->v)) {
int end = 0, len = itl->r - itl->l + 1;
if (len > num) {
end = itl->l + num - 1;
num = 0;
assign(itl->l, end, 1);
}
else {
num -= len;
itl->v = 1;
}
}
itl++;
}
}

int calc(int l, int r) {
IT itr = split(r + 1), itl = split(l);
int ans = 0, now = 0;
while (itl != itr) {
if (itl->v) {
ans = MAX(ans, now);
now = 0;
}
else now += itl->r - itl->l + 1;
itl++;
}
return MAX(ans, now);
}

void write(int x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}

signed main() {
s.insert(node(1, n, 1));
s.insert(node(n + 1, n + 1, 0));
rep(i, 1, m) {
int a, b, l, r, opt;
if (!opt) assign(l, r, 0);
else if (opt == 1) {
int num = sum(l, r);
assign(l, r, 0);
repair(a, b, num);
}
else {
write(calc(l, r));
printf("\n");
}
}
return 0;
}```
View Code