题解:CF1467D Sum of Paths
William2022 · · 题解
CF1467D Sum of Paths
切入
操作会变更元素的值,十分麻烦,但发现每个元素的贡献次数是固定的。
这么说,对于第
我们仅需算出数组
解法
最开始想到一个二维 DP,
从可能到达自己的位置向自己转移,容易想出这样推:
-
dp_{0,j}=1 -
dp_{i,j}=dp_{i-1,j-1}+dp_{i-1,j+1}
然后
仔细思考,发现只有结尾的计数是对的,而
怎么可能每一个节点作为起点只有一次啊?
于是开始思考,当
所以
因此
程序设计
先求出答案为
当第
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5005,M=1e9+7;
ll n,m,q,a[N],dp[N][N];
ll contribute[N];
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>n>>m>>q;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)dp[0][i]=1;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++)dp[i][j]=(dp[i-1][j-1]+dp[i-1][j+1])%M;
}
for(int i=1;i<=n;i++)for(int j=0;j<=m;j++){
contribute[i]+=(dp[j][i]*dp[m-j][i])%M;
contribute[i]%=M;
}
ll ans=0;
for(int i=1;i<=n;i++)(ans+=(a[i]*contribute[i])%M)%=M;
while(q--){
int x,y;
cin>>x>>y;
ans-=(a[x]*contribute[x])%M;
ans=(ans%M+M)%M;
a[x]=y;
ans+=(a[x]*contribute[x])%M;
ans%=M;
cout<<ans<<"\n";
}
}