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