比赛 |
2025暑期集训第2场 |
评测结果 |
AAAAAAAAAA |
题目名称 |
序列操作 |
最终得分 |
100 |
用户昵称 |
LikableP |
运行时间 |
1.384 s |
代码语言 |
C++ |
内存使用 |
9.42 MiB |
提交时间 |
2025-06-29 17:19:22 |
显示代码纯文本
#include <algorithm>
#include <cstdio>
const int MAXN = 1e5 + 10;
struct NODE {
int prefixone, prefixzero;
int suffixone, suffixzero;
int maxsubone, maxsubzero;
int len;
int sum;
int set_tag, set_to;
int reverse_tag;
} node[MAXN << 2];
template <typename T> T read();
template <typename T> void write(T, char);
template <typename T> T max(T, T);
void Merge(NODE, NODE, NODE &);
void Build(int, int, int);
void PushDown(int, int, int);
void Set(int, int, int, int, int, int);
void Reverse(int, int, int, int, int);
NODE Ask(int, int, int, int, int);
void Print(int, int, int);
int n, m;
int a[MAXN];
int main() {
freopen("sequence.in", "r", stdin);
freopen("sequence.out", "w", stdout);
n = read<int>(), m = read<int>();
for (int i = 1; i <= n; ++i) {
a[i] = read<int>();
}
Build(1, 1, n);
while (m--) {
int op = read<int>(), l = read<int>(), r = read<int>();
l++, r++;
if (op == 0) Set(1, 1, n, l, r, 0);
else if (op == 1) Set(1, 1, n, l, r, 1);
else if (op == 2) Reverse(1, 1, n, l, r);
else if (op == 3) write(Ask(1, 1, n, l, r).sum, '\n');
else if (op == 4) write(Ask(1, 1, n, l, r).maxsubone, '\n');
// Print(1, 1, n);
// printf("\n");
}
return 0;
}
#define ls(root) root << 1
#define rs(root) root << 1 | 1
void Merge(NODE A, NODE B, NODE &C) {
C.sum = A.sum + B.sum;
C.len = A.len + B.len;
C.prefixone = A.prefixone;
if (A.prefixone == A.len) C.prefixone += B.prefixone;
C.suffixone = B.suffixone;
if (B.suffixone == B.len) C.suffixone += A.suffixone;
C.prefixzero = A.prefixzero;
if (A.prefixzero == A.len) C.prefixzero += B.prefixzero;
C.suffixzero = B.suffixzero;
if (B.suffixzero == B.len) C.suffixzero += A.suffixzero;
C.maxsubone = max(max(A.maxsubone, B.maxsubone), A.suffixone + B.prefixone);
C.maxsubzero = max(max(A.maxsubzero, B.maxsubzero), A.suffixzero + B.prefixzero);
}
void Build(int root, int lt, int rt) {
if (lt == rt) {
node[root].len = 1;
node[root].set_tag = node[root].reverse_tag = node[root].set_to = 0;
if (a[lt]) {
node[root].prefixone = node[root].suffixone = node[root].maxsubone = node[root].sum = 1;
} else {
node[root].prefixzero = node[root].suffixzero = node[root].maxsubzero = 1;
}
return;
}
int mid = lt + ((rt - lt) >> 1);
Build(ls(root), lt, mid);
Build(rs(root), mid + 1, rt);
Merge(node[ls(root)], node[rs(root)], node[root]);
}
void Print(int root, int lt, int rt) {
// printf("###{%d sum:%d prefixon:%d suffixone:%d maxsubone:%d prefixzero:%d suffixzero:%d maxsubzero:%d}\n", root, node[root].sum, node[root].prefixone, node[root].suffixone, node[root].maxsubone, node[root].prefixzero, node[root].suffixzero, node[root].maxsubzero);
if (lt == rt) return;
PushDown(root, lt, rt);
int mid = lt + ((rt - lt) >> 1);
Print(ls(root), lt, mid);
Print(rs(root), mid + 1, rt);
}
void PushDown(int root, int lt, int rt) {
int mid = lt + ((rt - lt) >> 1);
if (node[root].set_tag) {
Set(ls(root), lt, mid, lt, mid, node[root].set_to);
Set(rs(root), mid + 1, rt, mid + 1, rt, node[root].set_to);
node[root].set_tag = false;
}
if (node[root].reverse_tag) {
Reverse(ls(root), lt, mid, lt, mid);
Reverse(rs(root), mid + 1, rt, mid + 1, rt);
node[root].reverse_tag = false;
}
}
void Set(int root, int lt, int rt, int lq, int rq, int val) {
if (lt == lq && rt == rq) {
node[root].set_tag = true;
node[root].set_to = val;
node[root].reverse_tag = false;
if (val) {
node[root].prefixone = node[root].suffixone = node[root].maxsubone = node[root].sum = node[root].len;
node[root].prefixzero = node[root].suffixzero = node[root].maxsubzero = 0;
} else {
node[root].prefixzero = node[root].suffixzero = node[root].maxsubzero = node[root].len;
node[root].prefixone = node[root].suffixone = node[root].maxsubone = node[root].sum = 0;
}
return;
}
PushDown(root, lt, rt);
int mid = lt + ((rt - lt) >> 1);
if (rq <= mid) {
Set(ls(root), lt, mid, lq, rq, val);
} else if (lq > mid) {
Set(rs(root), mid + 1, rt, lq, rq, val);
} else {
Set(ls(root), lt, mid, lq, mid, val);
Set(rs(root), mid + 1, rt, mid + 1, rq, val);
}
Merge(node[ls(root)], node[rs(root)], node[root]);
}
void Reverse(int root, int lt, int rt, int lq, int rq) {
// printf("###[%d %d %d %d %d]\n", root, lt, rt, lq, rq);
// printf("###{sum:%d prefixon:%d suffixone:%d maxsubone:%d prefixzero:%d suffixzero:%d maxsubzero:%d}\n", node[root].sum, node[root].prefixone, node[root].suffixone, node[root].maxsubone, node[root].prefixzero, node[root].suffixzero, node[root].maxsubzero);
if (lt == lq && rt == rq) {
node[root].reverse_tag ^= 1;
::std::swap(node[root].prefixone, node[root].prefixzero);
::std::swap(node[root].suffixone, node[root].suffixzero);
::std::swap(node[root].maxsubone, node[root].maxsubzero);
node[root].sum = node[root].len - node[root].sum;
return;
}
PushDown(root, lt, rt);
int mid = lt + ((rt - lt) >> 1);
if (rq <= mid) {
Reverse(ls(root), lt, mid, lq, rq);
} else if (lq > mid) {
Reverse(rs(root), mid + 1, rt, lq, rq);
} else {
Reverse(ls(root), lt, mid, lq, mid);
Reverse(rs(root), mid + 1, rt, mid + 1, rq);
}
Merge(node[ls(root)], node[rs(root)], node[root]);
}
NODE Ask(int root, int lt, int rt, int lq, int rq) {
if (lt == lq && rt == rq) {
return node[root];
}
PushDown(root, lt, rt);
int mid = lt + ((rt - lt) >> 1);
if (rq <= mid) {
return Ask(ls(root), lt, mid, lq, rq);
} else if (lq > mid) {
return Ask(rs(root), mid + 1, rt, lq, rq);
} else {
NODE A = Ask(ls(root), lt, mid, lq, mid);
NODE B = Ask(rs(root), mid + 1, rt, mid + 1, rq);
NODE C;
Merge(A, B, C);
return C;
}
}
template <typename T> T max(T x, T y) {
return x > y ? x : y;
}
#define isdigit(ch) (ch >= '0' && ch <= '9')
template <typename T> T read() {
T res = 0, f = 1;
char ch = getchar();
for (; !isdigit(ch); ch = getchar())
if (ch == '-') f = -1;
for (; isdigit(ch); ch = getchar()) res = (res << 3) + (res << 1) + (ch ^ 48);
return res * f;
}
template <typename T> void write(T x, char ed) {
if (x < 0) x = -x, putchar('-');
static int sta[sizeof(T) << 2], top = 0;
do {
sta[++top] = x % 10;
x /= 10;
} while (x);
while (top) {
putchar(sta[top--] ^ 48);
}
putchar(ed);
}
#define rs(root) root << 1 | 1
#define ls(root) root << 1