1 solutions
-
0
C++ :
#define MAXS 5UL #define MAXM 10010UL #define ll long long #include <cstdio> #include <string> #include <cstring> #include <iostream> using namespace std; int p; struct Martix{ ll s[MAXS][MAXS]; inline void clr(){memset(s,0,sizeof(s));return;} inline void Install(){clr();s[1][2]=1;s[2][1]=2;s[2][3]=1;s[3][1]=1;s[4][1]=1;s[4][4]=1;return;} inline void Unit(){clr();for(int i=1;i<=4;i++) s[i][i]=1;return;} inline void Build(int a,int b,int c,int d){clr();s[1][1]=a;s[1][2]=b;s[1][3]=c;s[1][4]=d;return;} friend Martix operator * (Martix a,Martix b){ Martix temp;temp.clr(); for(int i=1;i<=4;i++){ for(int j=1;j<=4;j++){ for(int k=1;k<=4;k++){ temp.s[i][j]=(temp.s[i][j]+a.s[i][k]*b.s[k][j])%p; } } } return temp; } }; int n,m,next2[MAXM],t1,t2,a1,a2,T,tp; string ls1="0",ls2="1",metr,r; inline void GetNext(){ for(int i=1,k=0;i<m;i++){ while(metr[i]!=metr[k]&&k) k=next2[k]; if(metr[i]==metr[k]) k++; next2[i+1]=k; } return; } inline int KMP(string link){ int len2=link.size(),Ans=0; for(int i=0,j=0;i<len2;i++){ while(metr[j]!=link[i]&&j) j=next2[j]; if(metr[j]==link[i]) j++; if(j==m){ Ans++;j=next2[j]; } } return Ans; } Martix R,Ans,cy; inline void Work(){ string link; for(int i=2;i<=n;i++) r=ls2,ls2=ls1+ls2,ls1=r; if(n==0) link="0"; else link=ls2; GetNext();printf("%d",KMP(link)%p); return; } int main(){ scanf("%d%d%d",&n,&m,&p);cin>>metr; if(n<20){ Work();return 0; } while(ls1.size()<m||ls2.size()<m) r=ls2,ls2=ls1+ls2,ls1=r,tp++; GetNext();a1=KMP(ls1),a2=KMP(ls2),t1=KMP(ls1+ls2)-a1-a2,t2=KMP(ls2+ls1)-a1-a2,T=t1+t2; //tp == ls1 tp+1 == ls2 //f[tp] = a1,f[tp+1] = a2,f[tp+2]=t1+a1+a2; R.Build(t1+a1+a2,a2,a1,T);// tp+2 --> n int k=n-(tp+2);Ans.Unit();cy.Install(); // Ans=cy^k Ans=R*Ans; while(k){ if(k&1) Ans=Ans*cy; k>>=1;cy=cy*cy; }R=R*Ans; printf("%lld\n",R.s[1][1]); return 0; }
- 1
Information
- ID
- 18566
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- (None)
- Tags
- # Submissions
- 0
- Accepted
- 0
- Uploaded By