命运的X

命运的X

cjx 生成函数强。

思路

首先,设 \(f_i\) 为添加第 \(i\) 项后满足条件的概率,\(g_i\) 任意添加至第 \(i\) 项的概率。

我们要求的答案:

\[ans=\sum_{i=0} i\times f_i \]

我们把 \(f\) 放入生成函数中:

\[F=\sum_{i=0} f_i x^i \]

显然有 \(F(1)=1\)

\(F\) 进行取导。

\[F'=\sum_{i=1} i\times f_ix^{i-1} \]

发现有 \(ans=F'(1)\)

\(g\) 也用生成函数 \(G\) 表示出来。

考虑加入一个字符,那么有 \(xG=G+F\),即可能匹配,也可能不匹配。

移项得,\((x-1)G=F\)

导一下,\(G+(x-1)G'=F'\)

\(x=1\),得 \(G(1)=F'(1)\)

考虑对 \(G\) 做转移,每次向后添加一段 \(b\)。当然可能添加中途已经存在最后一段等于 \(b\) 的情况,我们也要考虑,那就有:

\[\frac{x^n}{m^n}G=\sum_{i=1}^n[i]F\cdot \frac{x^{n-i}}{m^{n-i}} \]

其中 \(i\) 满足,\(b[1,i]=b[n-i+1,n]\)

移项得:

\[G=\sum_{i=1}^n [i] F\cdot \frac{m^i}{x^i} \]

\(x=1\),对下式求和即可。

\[ans=G(1)=\sum_{i=1}^n[i]F(1)\cdot m^i \]

CODE

#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define N 200000
#define pll pair<ll,ll>

const int maxn=2e5+5;
const ll mod=998244353,base=20090327,mod1=1e9+7,mod2=1e9+9;

int n,m;
int b[maxn];

ll pw1[maxn],pw2[maxn],sum1[maxn],sum2[maxn];

inline void init()
{
    pw1[0]=pw2[0]=1;
    for(int i=1;i<=N;i++)
        pw1[i]=pw1[i-1]*base%mod1,
        pw2[i]=pw2[i-1]*base%mod2;
}

inline pll calc(int l,int r){return {(sum1[r]-sum1[l-1]*pw1[r-l+1]%mod1+mod1)%mod1,(sum2[r]-sum2[l-1]*pw2[r-l+1]%mod2+mod2)%mod2};}
inline void solve()
{
    ll tmp=1,ans=0;
    for(int i=1;i<=n;i++)
    {
        tmp=tmp*m%mod;
        if(calc(1,i)==calc(n-i+1,n)) ans=(ans+tmp)%mod;
    }
    printf("%lld\n",ans);
}

int main()
{
    freopen("x.in","r",stdin);
    freopen("x.out","w",stdout);
    int _;
    init();
    scanf("%d",&_);
    while(_--)
    {
        memset(sum1,0,sizeof(sum1));
        memset(sum2,0,sizeof(sum2));
        scanf("%d%d",&m,&n);
        for(int i=1;i<=n;i++) scanf("%d",&b[i]);
        for(int i=1;i<=n;i++)
            sum1[i]=(sum1[i-1]*base+b[i]%mod1)%mod1,
            sum2[i]=(sum2[i-1]*base+b[i]%mod2)%mod2;
        solve();
    }
}
posted @ 2024-10-30 08:40  彬彬冰激凌  阅读(32)  评论(0)    收藏  举报