标签:tor signed rip namespace code end ace c++ false
给定一个长度为 \(n\) 个序列,第 i 个位置权值为 \(a_i\),有 \(k\) 次移动,每次移动往左或者往右移动一格,不能出边界,对于这样一个连续移动 k 次后得到的长度为 k+1 的位置序列,我们称为好序列,它的权值是经过的每一个位置的 \(a_i\) 的和,多次经过需要累加。现在对所有起始位置,求所有好序列的权值和,有 q 次对序列权值的修改。答案对 \(10^9+7\) 取模。
设 \(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;
}
}
标签:tor signed rip namespace code end ace c++ false
原文地址:https://www.cnblogs.com/mollnn/p/14347938.html