解题报告 『[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 read() { 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() { n = read(), m = read(); s.insert(node(1, n, 1)); s.insert(node(n + 1, n + 1, 0)); rep(i, 1, m) { int a, b, l, r, opt; opt = read(), l = read(), r = read(); if (!opt) assign(l, r, 0); else if (opt == 1) { a = read(), b = read(); int num = sum(l, r); assign(l, r, 0); repair(a, b, num); } else { write(calc(l, r)); printf("\n"); } } return 0; }