码迷,mamicode.com
首页 > 其他好文 > 详细

[CF1467D] Sum of Paths - dp

时间:2021-01-30 12:16:33      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:tor   signed   rip   namespace   code   end   ace   c++   false   

[CF1467D] Sum of Paths - dp

Description

给定一个长度为 \(n\) 个序列,第 i 个位置权值为 \(a_i\),有 \(k\) 次移动,每次移动往左或者往右移动一格,不能出边界,对于这样一个连续移动 k 次后得到的长度为 k+1 的位置序列,我们称为好序列,它的权值是经过的每一个位置的 \(a_i\) 的和,多次经过需要累加。现在对所有起始位置,求所有好序列的权值和,有 q 次对序列权值的修改。答案对 \(10^9+7\) 取模。

Solution

\(f[i][j]\) 为到达点 j 走了 i 步的方案数,也是从 j 出发走了 i 步的合法序列数

转移为 \(f[i][j]=f[i-1][j-1]+f[i-1][j+1]\)

那么第 i 步经过 j 的方案数就是 \(f[i][j] \cdot f[k-i][j]\)

\(g[j]=\sum_i f[i][j]\),即每个点被经过的总次数,这个值是不会变的

然后动态维护一个答案即可

#include <bits/stdc++.h>
using namespace std;

#define int long long

signed main()
{
    ios::sync_with_stdio(false);

    int n, k, q;
    cin >> n >> k >> q;

    vector<int> a(n + 2);
    for (int i = 1; i <= n; i++)
        cin >> a[i];

    const int mod = 1e9 + 7;

    vector<vector<int>> f(k + 2, vector<int>(n + 2));
    vector<int> g(n + 2);
    int ans = 0;

    for (int j = 1; j <= n; j++)
        f[0][j] = 1;
    for (int i = 1; i <= k; i++)
        for (int j = 1; j <= n; j++)
            f[i][j] = f[i - 1][j - 1] + f[i - 1][j + 1],
            f[i][j] %= mod;
    for (int i = 0; i <= k; i++)
        for (int j = 1; j <= n; j++)
            g[j] = (g[j] + f[i][j] * f[k - i][j]) % mod;

    for (int i = 1; i <= n; i++)
        ans = (ans + g[i] * a[i]) % mod;

    for (int t = 1; t <= q; t++)
    {
        int i, x;
        cin >> i >> x;
        ans -= g[i] * a[i];
        a[i] = x;
        ans += g[i] * a[i];
        ans %= mod;
        ans += mod;
        ans %= mod;
        cout << ans << endl;
    }
}

[CF1467D] Sum of Paths - dp

标签:tor   signed   rip   namespace   code   end   ace   c++   false   

原文地址:https://www.cnblogs.com/mollnn/p/14347938.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!