Agoracoderconteste5278I máquina de escrever antiga (dp)
Análise: para cada string para calcular o peso, o número de contribuições de cada string está relacionado apenas ao comprimento da string atual e ao comprimento total da string digitada
1. Calcule o número de soluções com \ (i \)
\ (dp [i] [j] \) representa o número de soluções atualmente consideradas i vezes, com j caracteres
\ (dp [i] [j] \ rightarrow dp [i + 1] [max (j-1,0)], dp [i] [j] \ cdot 26 + dp [i + 1] [j + 1] \)
2. Para cada comprimento \ (i \) , enumere o peso de cada sequência, caracteres fixos começando em \ (k \) com um comprimento de \ (| s_j | \) , outros caracteres casualmente, para caracteres fixos Remova \ (26 ^ {| s_i |} \) e multiplique o número de posições iniciais \ (k \) para obter o número de soluções
const int N=1e3+10,P=1e9+7;
int n,m;
char s[N][N];
int len[N],a[N];
ll Pow[N],C[N][N],IPow[N];
ll qpow(ll x,ll k) {
ll res=1;
for(;k;k>>=1,x=x*x%P) if(k&1) res=res*x%P;
return res;
}
int main(){
Pow[0]=IPow[0]=1;
rep(i,1,N-1) Pow[i]=Pow[i-1]*26%P;
IPow[1]=qpow(26,P-2);
rep(i,1,N-1) IPow[i]=IPow[i-1]*IPow[1]%P;
n=rd(),m=rd();
C[0][0]=1;
rep(i,0,m-1) {
rep(j,0,i) {
(C[i+1][j+1]+=C[i][j]*26)%=P;
(C[i+1][max(j-1,0)]+=C[i][j])%=P;
}
}
rep(i,1,n) scanf("%s",s[i]+1),len[i]=strlen(s[i]+1),a[i]=rd();
ll ans=0;
rep(i,1,m) {
ll s=0;
rep(j,1,n) if(i>=len[j]) s=(s+1ll*(i-len[j]+1)*a[j]%P*IPow[len[j]])%P; // 权值贡献次数
ans=(ans+s*C[m][i])%P;//长度为i的所有次数
}
printf("%lld\n",ans);
}