概率生成函数\(g(x)=\sum_{i\geq 0}t_ix^i\)\(t_i\)表示结果为\(i\)的概率

\(f(x)\)表示i位表示串结束时长度为i的概率,\(G(x)\)表示i位表示串长度为i时不结束的概率

有如下关系
\[①:f(x)+g(x)=1+g(x)x\]
意义:\(f(x)+g(x)\)即为串长达\(i\)位的概率,即\(i-1\)位不结束的概率

定义一个字符串的border为一个既为它前缀又为它后缀的非空串

定义\(b_i\)表示\([[1,2,\cdots,i]\text{为给定串border}]\),设给定串长度为L

那么可以得到
\[②:g(x)\times ({1\over n}x)^{L}=\sum_{i=1}^L b_i\times f(x)\times ({1\over n}x)^{L-i}\]
意义:左边:在一个串后添加给定串,必然结束。右边:长i的border,使得串在添加到i个字符时结束后,仍会添加剩下的\(L-i\)个字符
\[①\to f^{'}(x)+g^{'}(x)=g^{'}(x)x+g(x)\]
\(x=1\)带入,\(f^{'}(1)=g(1)\),而\(f^{'}(1)\)即为答案
\[②\to g(1)=\sum_{i=1}^L b_i f(1)n^i\]
\(f(1)=1\),故\(\displaystyle g(1)=\sum_{i=1}^L b_in^i\)

故答案为\(\sum_{i=1}^L b_in^i\)


#include <bits/stdc++.h>
//#pragma GCC target("avx,avx2,sse4.2")
#define rep(q, a, b) for (int q = a, q##_end_ = b; q <= q##_end_; ++q)
#define dep(q, a, b) for (int q = a, q##_end_ = b; q >= q##_end_; --q)
#define mem(a, b) memset(a, b, sizeof a)
#define debug(a) cerr << #a << ' ' << a << "___" << endl
using namespace std;
// char buf[10000000], *p1 = buf, *p2 = buf;
#define Getchar() getchar()//p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 10000000, stdin), p1 == p2) ? EOF : *p1++
void in(int &r) {
    static char c;
    r = 0;
    while (c = Getchar(), c < 48);
    do
        r = (r << 1) + (r << 3) + (c ^ 48);
    while (c = Getchar(), c > 47);
}
const int mn=100005;
int n,T,len;
int as[mn];
const int base=100003;
const int mod=998244353;
int solve(){
    int l=0,r=0,B=1,Ml=1,ans=0;
    rep(q,1,len){
        l=(1LL*l*base+as[q])%mod;
        r=(1LL*B*as[len-q+1]+r)%mod;
        B=1LL*B*base%mod;
        Ml=Ml*n%10000;
        if(l==r)ans=(ans+Ml)%10000;
    }
    return ans;
}
int main(){
    in(n),in(T);
    while(T--){
        in(len);
        rep(q,1,len)in(as[q]);
        printf("%04d\n",solve());
    }
    return 0;
}
02-01 02:28