Loading

CodeForces -1467D Sum of Paths 动态规划

CodeForces -1467D Sum of Paths 动态规划

题意

定义一条好的路径为从任意点出发后恰好进行了\(k\)次移动产生的路径,这条路径的权值和为走过的点的权值和。

进行\(q\)次修改,每次将\(a_k\)改为\(x\),修改后询问此时所有好的路径的权值和。

分析

每次询问,都不会使原来的好路径更改,因为从贡献的角度考虑,只需要知道每个点的贡献次数即可。

这显然是可以DP的。\(dp[i][j]\)表示走了\(j\)步以后,当前点在\(i\)点的路径个数。

\[dp[i][j] = dp[i + 1][j - 1] + dp[i - 1][j-1] \]

\(i\)的贡献,枚举\(i\)点作为中间点

\[cnt[i] = \sum dp[i][j] \times dp[i][k - j] \]

修改O(1)就好了

代码

ll a[5005];
ll c[5005];
ll dp[5005][5005];

int main(){
	int n = rd();
	int k = rd();
	int q = rd();
	ll res = 0;
	for(int i = 1;i <= n;i++)
		a[i] = rd();
	for(int i = 1;i <= n;i++)
		dp[i][0] = 1;
	for(int i = 1;i <= k;i++)
		for(int j = 1;j <= n;j++)
			dp[j][i] = (dp[j - 1][i - 1] + dp[j + 1][i - 1]) % MOD;
	for(int i = 1;i <= n;i++)
		for(int j = 0;j <= k;j++)
			c[i] = (c[i] + dp[i][j] * dp[i][k - j] % MOD) % MOD;
	for(int i = 1;i <= n;i++)
		res = (res + a[i] * c[i] % MOD) % MOD;
	for(int i = 1;i <= q;i++){
		ll tmp = rd();
		ll x = rd();
		res = (res - a[tmp] * c[tmp] % MOD + MOD) % MOD;
		a[tmp] = x;
		res = (res + a[tmp] * c[tmp] % MOD + MOD) % MOD;
		cout << res << '\n';
	}	
}
posted @ 2021-02-05 21:22  MQFLLY  阅读(89)  评论(0编辑  收藏  举报