长度相同的字符串拥有相同的出现次数
dp[a][b]记录了在敲击a次时长度为b的字符串出现次数
图片说明
图片说明
图片说明

由于概率平均 每一个字符串出现占其中的图片说明

每一个长度为b的字符串又拥有b-i+1个长度为i的子串
于是敲击a次长度为i的某一个子串的出现次数为图片说明

#include <bits/stdc++.h>
using namespace std;
long long dp[10000][10000]={0};
long long cans[10000]={0};
const long long mod=1e9+7;
long long gcd(long long a,long long b,long long &x,long long &y)
{
    if (b)
    {
        long long c=gcd(b,a%b,x,y);
        long long t=x;
        x=y;
        y=t-a/b*y;
        return c;      
    }
    else
    {
        x=1,y=0;
        return a;
    }
}
long long inv(long long a)
{
    long long x,y,d=gcd(a,mod,x,y);
    if(d==1)
        if(x%mod<=0)return x%mod+mod;
        else return x%mod;
    else return -1;
}
long long qpow(long long a,long long b) {long long res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int main()
{
    long long l,q;
    cin>>q>>l;
    dp[0][0]=1;
    dp[0][1]=0;
    for (long long i=1;i<=l;i++)
    {
        dp[i][0]=(dp[i-1][0]+dp[i-1][1])%mod;
        for(long long j=1;j<i;j++) dp[i][j]=(dp[i-1][j-1]*26+dp[i-1][j+1])%mod;
        dp[i][i]=(dp[i-1][i-1]*26)%mod;
    }
    for (long long i=1;i<=l;i++)
        for(long long j=i;j<=l;j++)
            cans[i]=(cans[i]+dp[l][j]*(j-i+1)%mod*inv(qpow(26,i))%mod)%mod;
    long long ans=0;
    while(q--)
    {
        string s;long long score;
        cin>>s>>score;
        ans=(ans+cans[s.size()]*score%mod)%mod;
    }
    cout<<(ans+mod)%mod<<endl;
    return 0;
}