P2572 [SCOI2010] 序列操作
sb 了,写半天标记忘记下放了,改后一发就过了/ll/ll
警钟长鸣。
#include <bits/stdc++.h>
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define ll long long
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
inline int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') f = c == '-' ? -1 : f, c = getchar();
while (c >= '0' && c <= '9') x = (x<<3)+(x<<1)+(c^48), c = getchar();
return x*f;
}
inline void write(ll x) {
if (x < 0) x = -x, putchar('-');
if (x > 9) write(x/10);
putchar('0'+x%10);
}
const int N = 1e5+5, M = N<<2;
int n, m, a[N], s0[M], s1[M], m0[M], m1[M], l0[M], l1[M], r0[M], r1[M], col[M], rev[M], len[M];
struct node {
int l, r, x, len;
node (int l = 0, int r = 0, int x = 0, int len = 0) : l(l), r(r), x(x), len(len) {}
};
node operator + (node a, node b) {
node res;
res.l = a.l == a.len ? a.l+b.l : a.l;
res.r = b.r == b.len ? b.r+a.r : b.r;
res.x = max(max(a.x, b.x), a.r+b.l);
res.len = a.len+b.len;
return res;
}
void pushup(int p) {
s1[p] = s1[ls]+s1[rs];
s0[p] = s0[ls]+s0[rs];
m1[p] = max(max(m1[ls], m1[rs]), r1[ls]+l1[rs]);
m0[p] = max(max(m0[ls], m0[rs]), r0[ls]+l0[rs]);
l1[p] = l1[ls] == len[ls] ? l1[ls]+l1[rs] : l1[ls];
l0[p] = l0[ls] == len[ls] ? l0[ls]+l0[rs] : l0[ls];
r1[p] = r1[rs] == len[rs] ? r1[rs]+r1[ls] : r1[rs];
r0[p] = r0[rs] == len[rs] ? r0[rs]+r0[ls] : r0[rs];
}
void pushdown(int p) {
if (~col[p]) {
s1[ls] = m1[ls] = l1[ls] = r1[ls] = col[p] ? len[ls] : 0;
s0[ls] = m0[ls] = l0[ls] = r0[ls] = col[p] ? 0 : len[ls];
s1[rs] = m1[rs] = l1[rs] = r1[rs] = col[p] ? len[rs] : 0;
s0[rs] = m0[rs] = l0[rs] = r0[rs] = col[p] ? 0 : len[rs];
col[ls] = col[rs] = col[p], col[p] = -1;
rev[ls] = rev[rs] = 0;
}
if (rev[p]) {
swap(s1[ls], s0[ls]);
swap(m1[ls], m0[ls]);
swap(l1[ls], l0[ls]);
swap(r1[ls], r0[ls]);
swap(s1[rs], s0[rs]);
swap(m1[rs], m0[rs]);
swap(l1[rs], l0[rs]);
swap(r1[rs], r0[rs]);
rev[ls] ^= 1, rev[rs] ^= 1, rev[p] = 0;
}
}
void build(int p, int l, int r) {
col[p] = -1, len[p] = r-l+1;
if (l == r) {
s1[p] = m1[p] = l1[p] = r1[p] = a[l];
s0[p] = m0[p] = l0[p] = r0[p] = !a[l];
return;
}
int mid = l+r>>1;
build(ls, l, mid), build(rs, mid+1, r);
pushup(p);
}
void cover(int p, int l, int r, int ql, int qr, int x) {
if (qr < l || r < ql) return;
if (ql <= l && r <= qr) {
s1[p] = m1[p] = l1[p] = r1[p] = x ? len[p] : 0;
s0[p] = m0[p] = l0[p] = r0[p] = x ? 0 : len[p];
col[p] = x, rev[p] = 0;
return;
}
pushdown(p); int mid = l+r>>1;
cover(ls, l, mid, ql, qr, x), cover(rs, mid+1, r, ql, qr, x);
pushup(p);
}
void rever(int p, int l, int r, int ql, int qr) {
if (qr < l || r < ql) return;
if (ql <= l && r <= qr) {
swap(s1[p], s0[p]);
swap(m1[p], m0[p]);
swap(l1[p], l0[p]);
swap(r1[p], r0[p]);
rev[p] ^= 1;
return;
}
pushdown(p); int mid = l+r>>1;
rever(ls, l, mid, ql, qr), rever(rs, mid+1, r, ql, qr);
pushup(p);
}
int que_s1(int p, int l, int r, int ql, int qr) {
if (qr < l || r < ql) return 0;
if (ql <= l && r <= qr) return s1[p];
pushdown(p); int mid = l+r>>1;
return que_s1(ls, l, mid, ql, qr)+que_s1(rs, mid+1, r, ql, qr);
}
node que_m1(int p, int l, int r, int ql, int qr) {
if (qr < l || r < ql) return node();
if (ql <= l && r <= qr) return node(l1[p], r1[p], m1[p], r-l+1);
pushdown(p); int mid = l+r>>1;
node res = que_m1(ls, l, mid, ql, qr)+que_m1(rs, mid+1, r, ql, qr);
return res;
}
int main() {
n = read(), m = read();
for (int i = 1; i <= n; ++i) a[i] = read();
build(1, 1, n);
while (m--) {
int op = read(), l = read()+1, r = read()+1;
if (op <= 1) cover(1, 1, n, l, r, op);
else if (op == 2) rever(1, 1, n, l, r);
else if (op == 3) write(que_s1(1, 1, n, l, r)), enter;
else write(que_m1(1, 1, n, l, r).x), enter;
}
return 0;
}