题解:AT_arc174_a [ARC174A] A Multiply
题传。
先要将 \(C\) 分类。
- \(C > 0\),为了使答案更大,要乘上一个最大的区间和。
- \(C \le 0\),为了使答案更大,选择乘上一个最小的区间和,因为此时我们可以贪心地想,如果区间和越小,乘上一个负数或 \(0\) 后,答案减少得越小,甚至乘上负数,还会使答案增大,所以也可以用负负得正来解释。
当然我们也可以不进行操作。
要求区间和,我们选择前缀和即可。
因为前缀和求区间 \(l \sim r\) 的和是 \(sum_r - sum_{l - 1}\)。要求区间和的最值,我们固定 \(sum_r\) 就可以求 \(sum_{l - 1}\) 的最值,我们遍历一遍并动态维护一下区间和的最值即可。
注意 \(i \sim i + 1\) 我们可以视为不选区间与 \(C\) 相乘。
给一下代码:
#include <bits/stdc++.h> #define int long long using namespace std; inline int read() { int res = 0, f = 1; char c = getchar(); while (c > '9' || c < '0') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') { res = (res << 1) + (res << 3) + (c ^ 48); c = getchar(); } return f == 1 ? res : -res; } int n, c, a[(int)3e5 + 5], sum[(int)3e5 + 5]; signed main() { n = read(), c = read(); for (int i = 1; i <= n; ++i) a[i] = read(), sum[i] = sum[i - 1] + a[i]; if (c > 0) { int ans = -1e18, mi = 0; for (int i = 1; i <= n; ++i) { mi = min(sum[i], mi);//求 sum[i-1] 的最值,下同。 ans = max(ans, sum[i] - mi);//求和的最值,下同。 } cout << sum[n] - ans + c * ans;//计算答案下同。 } else { int ans = 1e18, mx = 0; for (int i = 1; i <= n; ++i) { mx = max(sum[i], mx); ans = min(ans, sum[i] - mx); } cout << sum[n] - ans + c * ans; } return 0; }
本文作者:luckycloud
本文链接:https://www.cnblogs.com/luckycloud/p/18091349
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步