洛谷P17589题解

分析

题意

给定长度为 nn 的 01 串,ai=1a_i=1 代表会员,00 代表不是。

一共有 mm 次翻转操作,每次操作指定位置 xx,可以把 axa_x 取反(00 变 11,11 变 00)。

我们可以任选其中一部分操作执行,目标是让最终序列里 11 的数量尽可能大,求这个最大值。

思路

同一个位置如果出现多次翻转操作,我们只关心这个位置有没有被选中翻转,翻转偶数次等于没翻,奇数次等于翻一次。所以对于每个位置:

  1. 如果这个位置在 mm 次操作里出现过:我们可以自主选择翻或者不翻。
    • 原数是 00:翻一下变成 11,赚 11 个会员,肯定翻。
    • 原数是 11:翻一下变成 00,亏 11 个会员,肯定不翻。
  2. 如果这个位置在 mm 次操作里没出现过:不能翻转,保持原样。

做法:

  1. 先统计原始串中 11 的总数。
  2. 标记所有在操作列表中出现过的下标。
  3. 遍历所有下标,如果下标被标记且原值是 00,说明我们可以把它翻成 11,答案加上这部分的数量。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 5;
char a[MAXN];
bool vis[MAXN];
int main() {
int n, m;
cin >> n >> m;
scanf("%s", a + 1);
int sum = 0;
for (int i = 1; i <= n; i++) {
if (a[i] == '1') sum++;
}
for (int i = 0; i < m; i++) {
int x;
cin >> x;
vis[x] = 1;
}
int res = 0;
for (int i = 1; i <= n; i++) {
if (vis[i] && a[i] == '0') res++;
}
cout << sum + res << endl;
return 0;
}

洛谷P17589题解
https://lijingshu2014.github.io/2026/10/04/洛谷P17589题解/
作者
lijingshu
发布于
2026年10月4日
许可协议