专栏文章
题解:CF1467D Sum of Paths
CF1467D题解参与者 4已保存评论 3
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mioyvc5j
- 此快照首次捕获于
- 2025/12/03 03:24 3 个月前
- 此快照最后确认于
- 2025/12/03 03:24 3 个月前
CF1467D Sum of Paths
切入
操作会变更元素的值,十分麻烦,但发现每个元素的贡献次数是固定的。
这么说,对于第 个元素存在贡献值 ,代表 在所有路径上被经过的次数总和,这样答案总为 。
我们仅需算出数组 即可算出答案,且单点修改,甚至是区间增减都不在话下。
这么说,对于第 个元素存在贡献值 ,代表 在所有路径上被经过的次数总和,这样答案总为 。
我们仅需算出数组 即可算出答案,且单点修改,甚至是区间增减都不在话下。
解法
最开始想到一个二维 DP, 表示所有长度为 的不同路径中, 作为终点的总次数。
从可能到达自己的位置向自己转移,容易想出这样推:
从可能到达自己的位置向自己转移,容易想出这样推:
然后 就行了吗?
仔细思考,发现只有结尾的计数是对的,而 是时候计数不正确。
怎么可能每一个节点作为起点只有一次啊?
仔细思考,发现只有结尾的计数是对的,而 是时候计数不正确。
怎么可能每一个节点作为起点只有一次啊?
于是开始思考,当 成为长度为 的路径上的第 位有多少次。
- 作为第 ,也就是终点,有 次。
- 从 位出发到第 位,与从第 位到第 位是等价的,有 次。
所以 成为长度为 的路径上的第 位有 次。
因此 。
因此 。
程序设计
先求出答案为 。
当第 个值从 改成 时,将答案增加 ,并输出。
CPP当第 个值从 改成 时,将答案增加 ,并输出。
#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";
}
}
相关推荐
评论
共 3 条评论,欢迎与作者交流。
正在加载评论...