Advertisement
yicongli

BZ4175-NTT

Apr 3rd, 2019
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.16 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define gc c=getchar()
  6. #define r(x) read(x)
  7. #define ll long long
  8.  
  9. template<typename T>
  10. inline void read(T&x){
  11.     T k=1;char gc;x=0;
  12.     while(!isdigit(c)){if(c=='-')k=-1;gc;}
  13.     while(isdigit(c))x=x*10+c-'0',gc;x*=k;
  14. }
  15.  
  16. const int p=1005060097;
  17. const int g=5;
  18. const int N=4e5+7;
  19.  
  20. inline int add(int a,int b){
  21.     return (a+=b)>=p?a-p:a;
  22. }
  23.  
  24. inline int sub(int a,int b){
  25.     return (a-=b)<0?a+p:a;
  26. }
  27.  
  28. inline ll qpow(ll a,ll b){
  29.     ll ans=1;
  30.     while(b){
  31.         if(b&1)(ans*=a)%=p;
  32.         (a*=a)%=p;
  33.         b>>=1;
  34.     }
  35.     return ans;
  36. }
  37.  
  38. int r[N];
  39. int w1[N];
  40. int w2[N];
  41. inline void DFT(int *A,int n){
  42.     for(int i=0;i<n;++i)if(i<r[i])swap(A[i],A[r[i]]);
  43.     for(int i=1;i<n;i<<=1){
  44.         for(int j=0;j<n;j+=(i<<1)){
  45.             int *w=w1,step=n/i/2;
  46.             for(int k=0;k<i;++k,w+=step){
  47.                 int u=A[j+k],v=(ll)A[j+k+i]*(*w)%p;
  48.                 A[j+k]=add(u,v);
  49.                 A[j+k+i]=sub(u,v);
  50.             }
  51.         }
  52.     }
  53. }
  54.  
  55. inline void IDFT(int *A,int n){
  56.     for(int i=0;i<n;++i)if(i<r[i])swap(A[i],A[r[i]]);
  57.     for(int i=1;i<n;i<<=1){
  58.         for(int j=0;j<n;j+=(i<<1)){
  59.             int *w=w2,step=n/i/2;
  60.             for(int k=0;k<i;++k,w+=step){
  61.                 int u=A[j+k],v=(ll)A[j+k+i]*(*w)%p;
  62.                 A[j+k]=add(u,v);
  63.                 A[j+k+i]=sub(u,v);
  64.             }
  65.         }
  66.     }
  67.     ll inv=qpow(n,p-2);
  68.     for(int i=0;i<n;++i)A[i]=A[i]*inv%p;
  69. }
  70.  
  71. struct SAM{
  72.     int tot;
  73.     int len[N],fa[N],to[N][26],siz[N],ord[N],cnt[N];
  74.  
  75.     inline int NewNode(int l,int *tr,int su){
  76.         ++tot;
  77.         len[tot]=l;
  78.         if(tr!=NULL)memcpy(to[tot],tr,26<<2);
  79.         fa[tot]=su;
  80.         return tot;
  81.     }
  82.  
  83.     inline int Extend(int u,int c){
  84.         int t=NewNode(len[u]+1,NULL,0);
  85.         for(;u&&!to[u][c];u=fa[u])to[u][c]=t;
  86.         if(!u){
  87.             fa[t]=1;
  88.             return t;
  89.         }
  90.         int v=to[u][c];
  91.         if(len[v]==len[u]+1){
  92.             fa[t]=v;
  93.             return t;
  94.         }
  95.         int x=NewNode(len[u]+1,to[v],fa[v]);
  96.         fa[t]=fa[v]=x;
  97.         for(;u&&to[u][c]==v;u=fa[u])to[u][c]=x;
  98.         return t;
  99.     }
  100.  
  101.     inline void build(char *s,int n){
  102.         int lst=NewNode(0,NULL,0);
  103.         for(int i=1;i<=n;++i)siz[lst=Extend(lst,s[i]-'a')]=1;
  104.         for(int i=1;i<=tot;++i)cnt[len[i]]++;
  105.         for(int i=1;i<=n;++i)cnt[i]+=cnt[i-1];
  106.         for(int i=1;i<=tot;++i)ord[cnt[len[i]]--]=i;
  107.         for(int i=tot;i>1;--i)siz[fa[ord[i]]]+=siz[ord[i]];
  108.     }
  109.  
  110.     int F[N];
  111.     int G[N];
  112.  
  113.     inline void solve(int k,int n){
  114.         ++n;
  115.         for(int i=2;i<=tot;++i){
  116.             if(siz[i]<n){
  117.                 F[siz[i]]=add(F[siz[i]],(ll)siz[i]*(len[i]-len[fa[i]])%p);
  118.             }
  119.         }
  120.         G[0]=1;
  121.         int len=1;
  122.         while(len<2*n-1)len<<=1;
  123.         for(int i=0;i<len;++i)r[i]=(r[i>>1]>>1)|((i&1)*(len>>1));
  124.         w1[0]=w2[0]=1;
  125.         w1[1]=qpow(g,(p-1)/len);
  126.         w2[1]=qpow(w1[1],p-2);
  127.         for(int i=2;i<len;++i)w1[i]=(ll)w1[i-1]*w1[1]%p;
  128.         for(int i=2;i<len;++i)w2[i]=(ll)w2[i-1]*w2[1]%p;
  129.         while(k){
  130.             DFT(F,len);
  131.             if(k&1){
  132.                 DFT(G,len);
  133.                 for(int i=0;i<len;++i)G[i]=(ll)G[i]*F[i]%p;
  134.                 IDFT(G,len);
  135.                 for(int i=n;i<len;++i)G[i]=0;
  136.             }
  137.             for(int i=0;i<len;++i)F[i]=(ll)F[i]*F[i]%p;
  138.             IDFT(F,len);
  139.             for(int i=n;i<len;++i)F[i]=0;
  140.             k>>=1;
  141.         }
  142.         printf("%d\n",G[--n]);
  143.         return ;
  144.     }
  145. }sam;
  146.  
  147. char s[N];
  148.  
  149. int main(){
  150.     freopen("tele.in","r",stdin);
  151.     freopen("tele.out","w",stdout);
  152.     int k,m;r(k),r(m);
  153.     scanf("%s",s+1);
  154.     int n=strlen(s+1);
  155.     sam.build(s,n);
  156.     sam.solve(k,m);
  157. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement