O(N)的预处理 以O(1)的时间求部分和
S[1, N] = a1 + a2 + ... + aN;
我们如果要求S[L, R]
a1 + a2 + ... + aL-1 + aL + ... + aR
就是要aL + ... + aR的部分 -》 S[R] - S[L - 1]
S[]怎么来 S[i] = S[i - 1] + a[i]
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
int pre[N];
int main() {
int N; cin >> N;
for (int i = 1; i <= N; i++) {
cin >> pre[i];
}
for (int i = 1; i <= N; i++) {
cout << pre[i] - pre[i - 1] << " \n"[i == N];
}
return 0;
}
类似高中的错位相减法
a1 + a2 + a3 + a4 + a5 +...
1-
a1 * 1 + a2 * 2 + a3 * 3 + a4 * 4
2-
a2 * 1 + a3 * 2 + a4 * 3 + a5 * 4
-> pre[4] - pre[0]
1得到2式子
cur - pre[4] - pre[0] + m * a[5]
以
4 2
5 4 -1 8 ans -> 15 这个为例子
我们先得到第一个
cur1 = 5 * 1 + 4 * 2 = 13
第二个
cur2 = 4 * 1 + -1 * 2 = 2
第三个
cur3 = -1 * 1 + 8 * 2 = 15
我们需要得到这样的结果 统计最大值
pre[] -》 前缀和
5 9 8 16
我们不乏可以发现
第一个是需要cur1 - 4得到 cur2 + 2 * a[2] ->
cur2 = 4 * 1 + -1 * 2
我们在拓展到m = 3的时候
5 3
5 4 -1 8 6 ans -> 33
pre[] -> 5 9 8 16 22
cur1 = 5 * 1 + 4 * 2 + -1 * 3 = 10
cur2 = 4 * 1 + -1 * 2 + 8 * 3 = 26
cur3 = -1 * 1 + 8 * 2 + 6 * 3 = 33
cur1 - 5 - 4 - 1 + 8 * 3这个值 得到 cur2
从这里你可以推出一个公式
-》
cur = cur - (pre[i + m - 1] - pre[i - 1]) + m * a[i]
最后取最大值就看了
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const int N = 2e5 + 5;
i64 a[N], pre[N];
int main() {
ios::sync_with_stdio(false); cin.tie(0);cout.tie(0);
int n, m; cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) pre[i] = pre[i - 1] + a[i];
i64 ans = -1e18, cur = 0;
for (int i = 1; i <= m; i++) {
cur += a[i] * i;
}
for (int i = 1; i <= n - m + 1; i++) {
ans = max(ans, cur);
if (i != n - m + 1) {
cur -= pre[i + m - 1] - pre[i - 1];
cur += m * a[i + m];
}
}
cout << ans;
return 0;
}