1 条题解
-
0
C. Asuna and the Mosquitoes 详细题解
一、问题重述
给定一个长度为 的非负整数数组 (初始全部为正)。允许操作:选择 使得 为奇数且 ,然后 ,。求经过任意次操作后,数组最大值最大能是多少。
二、核心观察
2.1 操作对奇偶性的影响
- 为奇数 一个奇数、一个偶数。
- 操作:奇数 变偶数,偶数 变奇数。即奇偶性互换。
- 因此,操作不改变数组中奇数的个数 。
2.2 总和的守恒
每次操作总和不变:。因此总和 是常数。
三、两种情况讨论
情况 1:所有数奇偶性相同(全奇或全偶)
无法进行任何操作(因为找不到一对奇偶不同的数)。答案为 。
情况 2:既有奇数又有偶数
设 为奇数个数, 为总和。
上界:最终最大值 。
$$M + (k-1)\cdot 1 + 0 + \cdots \le S \Rightarrow M \le S - k + 1 $$
原因:奇数个数 不变,最终数组至少要有 个奇数。总和固定,让一个数尽可能大时,其余数至少为 (因为奇数最小为 )。若最大值为 ,则:可达性:通过构造可以达到 :
- 将所有偶数加到某一个奇数 上(通过操作把偶数逐个合并到 )。
- 此时数组变为:(一个奇数),其余 个奇数保持不变,剩余位置为 。
- 对于剩下的 个奇数,每次:
- 将该奇数转移 到一个 位置(产生一个偶数 ,原奇数变为偶数)
- 再将这个偶数合并到 上
- 重复直到只剩一个奇数 和 个
- 最终数组为:,最大值 。
四、标程代码
#include <algorithm> #include <iostream> #include <vector> using namespace std; void solve() { int n; cin >> n; vector<int> a(n); long long sum = 0; int odd_cnt = 0; for (int i = 0; i < n; i++) { cin >> a[i]; sum += a[i]; odd_cnt += (a[i] & 1); } if (odd_cnt == 0 || odd_cnt == n) { // 全奇或全偶,无法操作 cout << *max_element(a.begin(), a.end()) << '\n'; } else { // 既有奇数又有偶数 cout << sum - odd_cnt + 1 << '\n'; } } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t--) { solve(); } return 0; }
五、示例验证
示例 1:
- 全奇数 → ,输出 ✅
示例 2:
- ,,输出 ✅
示例 3:
- ,,输出 ✅
示例 4:
- ,,输出 ✅
六、复杂度分析
- 每个测试用例
- 总 ,完全可行
七、总结
情况 条件 答案 全奇或全偶 或 奇偶混合 其他 核心:操作不改变奇数个数 ,总和 固定,最大元素最多为 ,且该上界可达。
- 1
信息
- ID
- 7280
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者