ABC401C
前缀和优化,当时没想到是前缀和优化,看样例陷入了陷阱,题目描述的的是A[i] = k项加起来而不是等于A[i-1] + A[i-2]。要仔细读题思考前缀和优化
递推公式优化
\(直接计算 A_i时,若每次累加前 K 项,时间复杂度为 (O(NK)),对于 10^6\) 的数据会超时。利用前缀和数组 S 优化:\(S[i] = A_0 + A_1 + \ldots + A_i\),则 \(A_i = S[i-1] - S[i-K-1]\)(当 \(i \geq K\) 时)。初始时 \(S[i] = i+1\)(因为前 K 项均为 1,前缀和为项数)\)
\(A[i] 可以通过前缀和数组 S 来计算:A[i] = S[i - 1] - S[i - K - 1]。这里的 S[i - 1] 代表 A[0] 到 A[i - 1] 的和\),
\(S[i - K - 1] 代表 A[0] 到 A[i - K - 1] 的和,二者相减就能得到 A[i - K] 到 A[i - 1] 的和,也就是 A[i] 的值。\)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int mod = 1e9;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, k;
cin >> n >> k;
vector<int> a(n + 1);
vector<int> s(n + 1);
a[0] = 1;
s[0] = 1;
for (int i = 1; i < k; i++) {
s[i] = s[i - 1] + 1;
a[i] = 1;
}
for (int i = k; i <= n; i++) {
int pre = s[i - 1];
int tmp = 0;
if (i - k - 1 >= 0) tmp = s[i - k - 1];
a[i] = (pre - tmp + mod) % mod;
s[i] = (s[i - 1] + a[i]) % mod;
}
cout << a[n] << endl;
return 0;
}

浙公网安备 33010602011771号