命运的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();
}
}

浙公网安备 33010602011771号