1 solutions

  • 0
    @ 2025-11-5 17:34:29

    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