【Codeforces 1467D】 Suma de caminos | dp, pensamiento

El compañero de equipo es demasiado fuerte ...

Tan pronto como las ideas se fusionen, será A, ¡pronto!

Idea principal:

Defina un buen camino si y solo si pasa kk después de comenzar desde cualquier puntok se mueve, defina el peso de este camino como el peso del punto de pasoai a_iunyoLa suma de qqModificado q veces, cada vezak a_kunkCambiar a xxx , pregunte la suma de los pesos de todos los caminos 'buenos' en este momento

Idea de pregunta:

Considere nnn es5000 50005 0 0 0 , entonces tal vezn 2 n ^ 2norte2 pretratamiento

Si averigua en cuántos caminos se encuentra cada posición, será más fácil resolver cada modificación.

Así que considere cómo calcular en cuántas rutas se encuentra cada ubicación

Primero, una ecuación
dp [i] [k] = dp [i - 1] [k - 1] + dp [i + 1] [k - 1] dp [i] [k] = dp [i-1] [ k -1] + dp [i + 1] [k-1]d p [ i ] [ k ]=d p [ i-1 ] [ k-1 ]+d p [ i+1 ] [ k-1 ]
El estado de esta ecuación es:dp [i] [k] dp [i] [k]d p [ i ] [ k ] significa izquierdakkEl número total de k pasos actualmente en el punto i

Entonces piensa al revés, este dp [i] [k] dp [i] [k]d p [ i ] [ k ] también se puede expresar eniiTengo que irkkEl número total de caminos que pueden llegar a cualquier punto en k pasos, lo contrario es muy simple.

Entonces, por un punto, enumerelo como el punto medio, enumerelo como el 0.0 paso,1 11 paso,2 22 pasos,3 3El punto medio del paso 3 , así que para eliiEl número total de i puntos como ruta es obviamente:
∑ k = 0 k = mdp [i] [k] ∗ dp [i] [m - k] \ sum_ {k = 0} ^ {k = m} dp [ i] [k] * dp [i] [mk]k = 0k = md p [ i ] [ k ]d p [ i ] [ m-k ]

Entonces el problema está resuelto ...
Estoy seguro de que escribiré la solución antes de que termine la prueba final. Si no lo cree, puede piratearlo.

Código:

/*** keep hungry and calm CoolGuang!  ***/
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e17+7;
const ll maxn = 1e6+700;
const ll mod= 1e9+7;
const ll up = 1e13;
const double eps = 1e-9;
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;}
ll n,m,p;
ll a[5005],c[5005];
ll dp[5005][5005];
int main(){
    
    
	read(n);read(m);read(p);

	for(int i=1;i<=n;i++) read(a[i]);
	for(int i=1;i<=n;i++) dp[i][0] = 1; 
	
	for(int k=1;k<=m;k++)
		for(int i=1;i<=n;i++)
			dp[i][k] = (dp[i-1][k-1] + dp[i+1][k-1])%mod;
	for(int i=1;i<=n;i++){
    
    
		for(int k=0;k<=m;k++){
    
    
			c[i] = (c[i] + (dp[i][k]*dp[i][m-k])%mod)%mod;
		}
	}
	ll ans = 0;
	for(int i=1;i<=n;i++) ans = (ans + (a[i] * c[i])%mod)%mod;
	for(int i=1;i<=p;i++){
    
    
		ll pos,x;
		read(pos);read(x);
		ans = (ans - (a[pos]*c[pos])%mod + mod)%mod;
		a[pos] = x;
		ans = (ans + (a[pos]*c[pos])%mod)%mod;
		printf("%lld\n",ans);
	}
	return 0;
}
/***
2 3
2 3 2
4 5 4 1 5
***/

Supongo que te gusta

Origin blog.csdn.net/qq_43857314/article/details/112386522
Recomendado
Clasificación