代码先锋网 代码片段及技术文章聚合

CodeForces 1467D :Sum of Paths DP + 贡献

技术标签: codeforces  DP

传送门

题目描述

一个长度为 n n n的线段,每个点都有一个价值 a i a_{i} ai,每经过这个点都会加上这个点的值,你可以从任意点开始,每次可以向左移动一格或者向右移动一格,问你移动 m m m次,所有可能的路径的的值的和是多少
q q q次修改,每次都会修改一个点的 a i a_{i} ai

分析

因为涉及到所有的方案,而这个数据范围肯定不会把每条路线弄出来,所以我们可以想办法把把这个路线给抽象出来
我们可以计算出每个点的贡献,也就是每个点经过的次数

 f[j][i] = (f[j - 1][i - 1] + f[j + 1][i - 1]) % mod;

然后,我们去枚举 i , j i,j i,j,假设我们第 j j j步走到了 i i i,那么这条路径一共可能的情况一共有 f [ i ] [ j ] ∗ f [ i ] [ m − j ] f[i][j] * f[i][m - j] f[i][j]f[i][mj],也就是说点 i i i一共经过了这么多次,所以这就是他的贡献值
最后求一下每个点的和, q q q次修改即可

代码

#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
#define _CRT_SECURE_NO_WARNINGS
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int N = 5010;
const ll mod= 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){char c=getchar();T x=0,f=1;while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
int gcd(int a,int b){return (b>0)?gcd(b,a%b):a;}
ll f[N][N],cnt[N];
ll a[N];
ll res;
int n,m,q;

int main(){
    read(n),read(m),read(q);
    for(int i = 1;i <= n;i++) {
        read(a[i]);
        f[i][0] = 1;
    }
    for(int i = 1;i <= m;i++)
        for(int j = 1;j <= n;j++)
            f[j][i] = (f[j - 1][i - 1] + f[j + 1][i - 1]) % mod;
    for(int i = 1;i <= n;i++)
        for(int j = 0;j <= m;j++)
            cnt[i] = (cnt[i] + (f[i][j] * f[i][m - j]) % mod) % mod;
    for(int i = 1;i <= n;i++) res = (res + (a[i] * cnt[i]) % mod) % mod;
    while(q--){
        int pos,x;
        read(pos),read(x);
        res = (res - a[pos] * cnt[pos] % mod + mod) % mod;
        a[pos] = x;
        res = (res + a[pos] * cnt[pos] % mod) % mod;
        dl(res);
    }
    return 0;
}

/**
*  ┏┓   ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃       ┃
* ┃   ━   ┃ ++ + + +
*  ████━████+
*  ◥██◤ ◥██◤ +
* ┃   ┻   ┃
* ┃       ┃ + +
* ┗━┓   ┏━┛
*   ┃   ┃ + + + +Code is far away from  
*   ┃   ┃ + bug with the animal protecting
*   ┃    ┗━━━┓ 神兽保佑,代码无bug 
*   ┃        ┣┓
*    ┃        ┏┛
*     ┗┓┓┏━┳┓┏┛ + + + +
*    ┃┫┫ ┃┫┫
*    ┗┻┛ ┗┻┛+ + + +
*/


版权声明:本文为tlyzxc原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/tlyzxc/article/details/114587242

智能推荐

CF698Div2-D. Sum of Paths-dp,组合数学

题目大意: 给你一个一维的方格 [ 1 , n ] [1,n] [1,n]。一个机器人每一步只能移动到相邻的格子上.现在问你所有长度为 k k k的合法路径中 x 1 → x 2 → . . . → x k x_1\rightarrow x_2\rightarrow ...\rightarrow x_k x1​→x2​→...→xk​,总...

CF 659 D - Sum of Paths dp E Tree树上差分

D - Sum of Paths 题目链接 D题题意是给一个数组,刚开始随便在一个点,之后随机向左向右走。只能在 1 − n 1 - n 1−n中走(不能越界),每走到一个点就加上这个位置的值,问走的所有路径的权值总和是多少。有m次查询,每次修改一个位置上的权值。 这题很显眼,就是统计每个点总过走多少次。(在所有的路径中出现的次数)于是可以想到 d p [ i ] [ j ...

Codeforces Round #695 (Div. 2) D. Sum of Paths

传送门 题目大意 有n个位置,机器人可以在任何位置出发,然后必须走k步,每次走可以往左或往右走一步,将路径的值加起来,就是此次走路的价值,算所有路的价值总和 题解 我们设dp[i][j]为用i步走过多少次j,首先我们不考虑中间经过j的次数,只算最终到j的情况,显然是dp[i][j]=dp[i-1][j-1]+dp[i-1][j+1],而中间经过的次数为dp[k-i][j]*dp[i][j]的和,及...

Codeforces Round #695 (Div. 2) D. Sum of Paths

题目大意 给出一个 n n n维数组 a 1 , a 2 , ⋯   , a n a_1,a_2,\cdots,a_n a1​,a2​,⋯,an​, 定义一条长度为 k k k的路径如下: 从一个点 c 0 c_0 c0​出发,可以向左一步到 c 0 − 1 c_0-1 c0​−1(当前不在最左边),向右走一步到 c 0 + 1 c_0+1 c0​+1(当前不...

Codeforces 1519D Maximum Sum of Products (区间DP)

Maximum Sum of Products 题目大意:给出两个长度为n的数组,你可以反转一次其任意子数组,也可以不反转,求对应位置的数的乘积之和 即求 ∑ 1 n a [ i ] ∗ b [ i ] {\textstyle \sum_{1}^{n}} a[i]*b[i] ∑1n​a[i]∗b[i] 解法:我们可以先算出其不反转的乘积之和再加上反转任意...

猜你喜欢

Maximum Sum of Products CodeForces - 1519D (区间DP)

题意 给出两个长度为n ( 1 ≤ n ≤ 5000 ) a , b 可以最多一次对序列a 的某段子数组执行翻转操作,求出如何翻转使得 ∑ i = 1 n a i ∗ b i \sum_{i=1}^{n}a_{i}*b_{i} ∑i=1n​ai​∗bi​最大。 思路 跑一遍区间DP,状态转移方程为 d p [ i ] [ j ] = d p ...

Codeforces 705D Ant Man DP(贡献)

题意:n个点的完全有向图.边权为:|xi-xj|+ci+bj (j<i) |xi-xj|+di+aj (j>i) 求从s出发,经过每个点正好一次达到t的最短路径? n<=5000 按上面直接连边后,变成求最短哈密顿路??? 边的值不是任意的,和两点的距离以及其对应a,b,c,d有关,把边的累加和拆成每个单点贡献后的累加和. 一个结点可以有4个状态:路径中pre为左/右,nxt为左...

使用systemd-coredump调试应用程序崩溃

使用systemd-coredump调试应用程序崩溃 systemd-coredump收集并显示内核核心转储,以分析应用程序崩溃。当某个进程崩溃(或所有属于某个应用程序的进程)时,其默认设置是将核心转储记录到日志中(systemd如果可能的话包括回溯),并将核心转储存储在中的文件中 /var/lib/systemd/coredump。您还可以选择使用其他工具(例如gdb或crash) 检查转储文件...

H5移动端实现手机震动效果

判断兼容 浏览器对振动API的支持情况,一个好的习惯就是在使用之前要检查一下当前你的应用环境、浏览器是否支持振动API。下面就是检测的方法: 在window.navigator对象里就只有一个关于振动的API:vibrate。 振动API基础应用 这个navigator.vibrate函数可以接受一个数字参数,也可以接受一个数字数组,当使用数组参数时,奇数位的数值是震动秒数,偶数位为等待秒数。 如...

vue的data、计算属性一些小细节

vue初始化的顺序: props methods data computed watch 所以一般不会在data里面直接使用computed的值, 计算属性是响应式的 Original message: "Hello" Computed reversed message: "olleH" 这里我们声明了一个计算属性 reversedMessage。...