题意:一个串 T 是 S 的周期,当且仅当存在正整数 k,使得 S 是 T 重复 k 次的前缀,比如 abcd 是 abcdabcdab 的周期。
给定一个长度为 n 的字符串 S,请对于每个 i(1 ≤ i ≤ n),求出 S 长度为 i 的前缀的最短周期的长度 peri,并计算 f(S)=Πni=1peri
如果这个串是从所有长度为 n,字符集为 m 的字符串中随机选取的,那么这个 f(S) 的值期望 E 应该是多少?输出E × m^n mod 998244353
n<=12,m<=1e9
用最小表示法表示一个串,长度为12的串最多有4213597个。
然后再对每个串做一遍kmp,最短循环节长度=n-Next[i]
#include<bits/stdc++.h>
using namespace std;
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma
#define
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define
int n,m;
int a[MAXN];
ll ans=0,Next[MAXN];
ll A[MAXN]; //A(m,i)
ll work() {
// PRi(a,n)
Next[0]=0;
int p=0;
For(i,n) {
while(p && a[p+1]!=a[i]) p=Next[p];
if (p+1!=i&&a[p+1]==a[i]) ++p;
Next[i]=p;
}
// PRi(Next,n)
ll ret=1;
For(i,n) (ret*=(i-Next[i]))%=F;
return ret;
}
void dfs(int l,int p) {
if (l>n) {
upd(ans,mul(A[p],work() ));
return;
}
For(i,p) {
a[l]=i;
dfs(l+1,p);
}
a[l]=p+1;dfs(l+1,p+1);
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
cin>>n>>m;
A[0]=1;
For(i,n) A[i]=A[i-1] * (m-i+1)%F;
dfs(1,0);
cout<<ans<<endl;
return 0;
}