Problem A magic
给出一个字符串$S$,和数字$n$,要求构造长度为$n$只含有小写字母的字符串$T$,
使得在$T$中存在删除且仅删除一个子串使得$S=T$成立。
输出$T$的构造方案数,mod 998244353的值。
对于$100 \% $的数据 $2 \leq n \leq 10^{18} , |S| \leq 10^6$
Sol : 考虑$T$合法的条件是和$S$有相同的前缀和相同的后缀,且相同前后缀长度和是$|S|$
若最长公共前缀长度为$0$ ,那么说明$S$和$T$最后$|S|$位相同,合法情况$T$的取值有$26^{n - |S|}$ 种。
若最长公共前缀长度不为$0$ ,那么说明前半部分至少有$k$是$S$的前缀,后半部分就有$|S| - k $的长度是后缀,这个时候由于倒数$|S| - k$ 个 不能和上一次一样,这个位置只有$25$种可能,其他位置是$26$种可能,这种情况下方案数时$26^{n-|S|-1}$
最后答案就是$26^n - 26^{n-1} - |S|\times 25 \times 26^{n-|S|-1}$
注意需要特判$n = |S|$的情况,答案就是$26 ^ n - 1$
复杂度是$O(log_2 n)$
#include<bits/stdc++.h> using namespace std; const long long mod=998244353; long long n,m; char tmp[1000100]; long long Pow(long long x,long long k) { if(k<0) return 0ll; if(!k) return 1ll; long long res=Pow(x,k/2); res=res*res%mod; if(k%2) res=res*x%mod; return res; } int main() { scanf("%lld %s",&n,tmp); m=strlen(tmp); printf("%lld",(long long)(Pow(26ll,n)-(Pow(26ll,n-m)%mod+(m*25ll%mod)*Pow(26ll,n-m-1)%mod)%mod+mod)%mod); return 0; }