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;
}
A.cpp

相关文章:

  • 2021-11-02
  • 2021-09-30
  • 2021-07-06
  • 2021-09-11
  • 2021-05-19
  • 2021-08-01
  • 2021-06-08
  • 2022-03-08
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案