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;
}    
posted @ 2025-04-15 16:43  啦啦啦456123  阅读(12)  评论(0)    收藏  举报