解题报告 『[SCOI2010]序列操作(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++) const int maxn = 1e5 + 5; int n, m; int a[maxn]; struct node { int l,r; mutable bool v; node(int L, int R = -1, int V = 0): l(L), r(R), v(V) {} bool 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)); } void rever(int l, int r) { IT itr = split(r + 1), itl = split(l); while (itl != itr) { itl->v ^= 1; itl++; } } 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; } int con_sum(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(); rep(i, 0, n - 1) { a[i] = read(); s.insert(node(i, i, a[i])); } s.insert(node(n, n, 0)); rep(i, 1, m) { int l, r, opt; opt = read(), l = read(), r = read(); if(!opt) assign(l, r, 0); else if (opt == 1) assign(l, r, 1); else if (opt == 2) rever(l, r); else if (opt == 3){ write(sum(l, r)); printf("\n"); } else { write(con_sum(l, r)); printf("\n"); } } return 0; }