只过了 Hack 和 #2
#include <tuple>
#include <cstdio>
#include <algorithm>
#define lson(now) (now << 1)
#define rson(now) (now << 1 | 1)
const int N = 1e5 + 5;
int n, m;
int a[N];
struct Segment_Tree
{
int cov[N << 2], rev[N << 2];
int sum[N << 2], suf[N << 2], sub[N << 2], pre[N << 2];
int sub0[N << 2], pre0[N << 2], suf0[N << 2];
void cover(int now, int s, int t, bool val)
{
if (val == 1)
{
sum[now] = sub[now] = suf[now] = pre[now] = t - s + 1;
sub0[now] = suf0[now] = pre0[now] = 0;
}
else
{
sum[now] = sub[now] = suf[now] = pre[now] = 0;
sub0[now] = suf0[now] = pre0[now] = t - s + 1;
}
}
void reverse(int now, int s, int t)
{
sum[now] = (t - s + 1) - sum[now];
std::swap(sub[now], sub0[now]);
std::swap(pre[now], pre0[now]);
std::swap(suf[now], suf0[now]);
}
void pushup(int now, int s, int t)
{
int mid = (s + t) >> 1;
sum[now] = sum[lson(now)] + sum[rson(now)];
sub[now] = std::max({sub[lson(now)],
sub[rson(now)],
suf[lson(now)] + pre[rson(now)]});
suf[now] = sum[rson(now)] == (t - mid) ?
suf[lson(now)] + t - mid :
suf[rson(now)];
pre[now] = sum[lson(now)] == (mid - s + 1) ?
mid - s + 1 + pre[rson(now)] :
pre[lson(now)];
sub0[now] = std::max({sub0[lson(now)],
sub0[rson(now)],
suf0[lson(now)] + pre0[rson(now)]});
suf0[now] = sum[rson(now)] ?
suf0[rson(now)] :
(t - mid) + suf0[lson(now)];
pre0[now] = sum[lson(now)] ?
pre0[lson(now)] :
(mid - s + 1) + pre0[rson(now)];
}
void pushdown(int now, int s, int t)
{
int mid = (s + t) >> 1;
if (cov[now] != -1)
{
cover(lson(now), s, mid, cov[now]);
cover(rson(now), mid + 1, t, cov[now]);
cov[lson(now)] = cov[rson(now)] = cov[now];
rev[lson(now)] = rev[rson(now)] = 0;
cov[now] = -1;
}
if (rev[now])
{
reverse(lson(now), s, mid);
reverse(rson(now), mid + 1, t);
rev[lson(now)] ^= 1;
rev[rson(now)] ^= 1;
//if (rev[lson(now)])
// cov[lson(now)] ^= 1;
//if (rev[rson(now)])
// cov[rson(now)] ^= 1;
rev[now] = 0;
}
}
void build(int s, int t, int now)
{
cov[now] = -1;
if (s == t)
{
sum[now] = sub[now] = pre[now] = suf[now] = a[s];
sub0[now] = pre0[now] = suf0[now] = !a[s];
return;
}
int mid = (s + t) >> 1;
build(s, mid, lson(now));
build(mid + 1, t, rson(now));
pushup(now, s, t);
}
void modify_cov(int l, int r, int s, int t, int now, bool val)
{
if (l <= s && t <= r)
{
cov[now] = val;
cover(now, s, t, val);
return;
}
int mid = (s + t) >> 1;
pushdown(now, s, t);
if (mid >= l)
modify_cov(l, r, s, mid, lson(now), val);
if (mid < r)
modify_cov(l, r, mid + 1, t, rson(now), val);
pushup(now, s, t);
}
void modify_rev(int l, int r, int s, int t, int now)
{
if (l <= s && t <= r)
{
rev[now] ^= 1;
reverse(now, s, t);
return;
}
int mid = (s + t) >> 1;
pushdown(now, s, t);
if (mid >= l)
modify_rev(l, r, s, mid, lson(now));
if (mid < r)
modify_rev(l, r, mid + 1, t, rson(now));
pushup(now, s, t);
}
int query_sum(int l, int r, int s, int t, int now)
{
if (l <= s && t <= r)
return sum[now];
int mid = (s + t) >> 1, res(0);
pushdown(now, s, t);
if (mid >= l)
res += query_sum(l, r, s, mid, lson(now));
if (mid < r)
res += query_sum(l, r, mid + 1, t, rson(now));
pushup(now, s, t);
return res;
}
std::tuple < int, int, int, int >
query_sub(int l, int r, int s, int t, int now)
{
//printf("%d: %d %d %d %d\n", now, pre[now], sub[now], suf[now], sum[now]);
if (l <= s && t <= r)
return std::make_tuple(pre[now], sub[now], suf[now], sum[now]);
int mid = (s + t) >> 1;
int sb, pr, sf, sm, _sb, _pr, _sf, _sm;
std::tuple < int, int, int, int > tp;
pushdown(now, s, t);
if (mid >= l)
{
if (mid < r)
{
tp = query_sub(l, r, s, mid, lson(now));
sb = std::get < 1 > (tp);
pr = std::get < 0 > (tp);
sf = std::get < 2 > (tp);
sm = std::get < 3 > (tp);
tp = query_sub(l, r, mid + 1, t, rson(now));
_sb = std::get < 1 > (tp);
_pr = std::get < 0 > (tp);
_sf = std::get < 2 > (tp);
_sm = std::get < 3 > (tp);
sb = std::max({sb, _sb, sf + _pr});
sb = std::max({sb, _sb, sf + _pr});
pr = sm == (mid - s + 1) ? sm + _pr : pr;
sf = _sm == (t - mid) ? _sm + sf : _sf;
sm = sm + _sm;
pushup(now, s, t);
return std::make_tuple(pr, sb, sf, sm);
}
tp = query_sub(l, r, s, mid, lson(now));
pushup(now, s, t);
return tp;
}
tp = query_sub(l, r, mid + 1, t, rson(now));
pushup(now, s, t);
return tp;
}
void dfs(int s, int t, int now)
{
if (s == t)
{
printf("%d ", sum[now]);
return;
}
int mid = (s + t) >> 1;
pushdown(now, s, t);
dfs(s, mid, lson(now));
dfs(mid + 1, t, rson(now));
pushup(now, s, t);
}
}
SegT;
int opt, l, r;
int main()
{
scanf("%d %d", &n, &m);
int i;
for (i = 1; i <= n; i++)
scanf("%d", &a[i]);
SegT.build(1, n, 1);
while (m--)
{
scanf("%d %d %d", &opt, &l, &r);
l++, r++;
if (opt == 0)
SegT.modify_cov(l, r, 1, n, 1, 0);
else if (opt == 1)
SegT.modify_cov(l, r, 1, n, 1, 1);
else if (opt == 2)
SegT.modify_rev(l, r, 1, n, 1);
else if (opt == 3)
printf("%d\n", SegT.query_sum(l, r, 1, n, 1));
else if (opt == 4)
printf("%d\n", std::get < 1 > (SegT.query_sub(l, r, 1, n, 1)));
}
return 0;
}