比赛 |
2025暑期集训第2场 |
评测结果 |
AAAAAAAAAA |
题目名称 |
序列操作 |
最终得分 |
100 |
用户昵称 |
OTTF |
运行时间 |
2.179 s |
代码语言 |
C++ |
内存使用 |
11.73 MiB |
提交时间 |
2025-06-29 17:02:37 |
显示代码纯文本
#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;
constexpr int N = 114514;
int n;
int m;
int nums[N];
struct node {
int len;
int num[2][4]; // sum left right together
int become;
int change;
friend node operator+ (node one, node two);
};
node zero;
node operator+ (node one, node two) {
node res;
res.len = one.len + two.len;
res.become = -1;
res.change = 0;
for (int i = 0; i < 2; i++) {
res.num[i][0] = one.num[i][0] + two.num[i][0];
res.num[i][1] = one.num[i][1] + (one.num[i][1] == one.len) * two.num[i][1];
res.num[i][2] = two.num[i][2] + (two.num[i][2] == two.len) * one.num[i][2];
res.num[i][3] = max ({one.num[i][3], two.num[i][3], one.num[i][2] + two.num[i][1]});
}
return res;
}
node tree[N * 4];
inline int lson (int now) {
return now * 2;
}
inline int rson (int now) {
return now * 2 + 1;
}
void build (int now, int nowl, int nowr) {
if (nowl == nowr) {
tree[now].len = 1;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 4; j++) {
tree[now].num[i][j] = (nums[nowl] == i);
}
}
tree[now].become = -1;
tree[now].change = 0;
return;
}
int m = (nowl + nowr) / 2;
build (lson (now), nowl, m);
build (rson (now), m + 1, nowr);
tree[now] = tree[lson (now)] + tree[rson (now)];
tree[now].become = -1;
tree[now].change = 0;
}
void giveMark (int now, int mark) {
if (mark <= 1) {
tree[now].become = mark;
tree[now].change = 0;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 4; j++) {
tree[now].num[i][j] = (mark == i) * tree[now].len;
}
}
}
else {
tree[now].change ^= 1;
swap (tree[now].num[0], tree[now].num[1]);
}
}
void pushDown (int now) {
if (tree[now].become != -1) {
giveMark (lson (now), tree[now].become);
giveMark (rson (now), tree[now].become);
}
if (tree[now].change) {
giveMark (lson (now), 2);
giveMark (rson (now), 2);
}
tree[now].become = -1;
tree[now].change = 0;
}
void update (int now, int nowl, int nowr, int l, int r, int num) {
if (l <= nowl && nowr <= r) {
giveMark (now, num);
return;
}
pushDown (now);
int m = (nowl + nowr) / 2;
if (l <= m) {
update (lson (now), nowl, m, l, r, num);
}
if (m + 1 <= r) {
update (rson (now), m + 1, nowr, l, r, num);
}
tree[now] = tree[lson (now)] + tree[rson (now)];
}
node query (int now, int nowl, int nowr, int l, int r) {
if (l <= nowl && nowr <= r) {
return tree[now];
}
pushDown (now);
int m = (nowl + nowr) / 2;
if (r <= m) {
return query (lson (now), nowl, m, l, r);
}
if (m + 1 <= l) {
return query (rson (now), m + 1, nowr, l, r);
}
return query (lson (now), nowl, m, l, r) + query (rson (now), m + 1, nowr, l, r);
}
int main () {
freopen ("sequence.in", "r", stdin);
freopen ("sequence.out", "w", stdout);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> nums[i];
}
build (1, 1, n);
int op, l, r;
for (int i = 1; i <= m; i++) {
cin >> op >> l >> r;
l++;
r++;
if (op <= 2) {
update (1, 1, n, l, r, op);
}
else {
node res = query (1, 1, n, l, r);
if (op == 3) {
cout << res.num[1][0] << endl;
}
else {
cout << res.num[1][3] << endl;
}
}
}
return 0;
}