概率生成函数(g(x)=sum_{igeq 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] ext{为给定串border}]),设给定串长度为L
那么可以得到
[②:g(x) imes ({1over n}x)^{L}=sum_{i=1}^L b_i imes f(x) imes ({1over n}x)^{L-i}
]
意义:左边:在一个串后添加给定串,必然结束。右边:长i的border,使得串在添加到i个字符时结束后,仍会添加剩下的(L-i)个字符
[① o f^{'}(x)+g^{'}(x)=g^{'}(x)x+g(x)
]
将(x=1)带入,(f^{'}(1)=g(1)),而(f^{'}(1))即为答案
[② o 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
",solve());
}
return 0;
}