[BZOJ1009][HNOI2008]GT Exam (KMP+DP)

[ Unstable portal

Solution

dp[i][j] indicates that the first i characters are currently matched to the jth of the unlucky string, that is, the suffix of the current scheme is equal to the prefix of the unlucky string

However, because n is too large, it cannot be transferred directly, and matrix optimization is used.

Code

 

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

char s[120];
int n,m,mo,nex[120];

inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

struct info{
	int n,m,A[30][30];
	info(int a,int b):n(a),m(b){memset(A,0,sizeof(A));}
	int *operator [](int x){return A[x];}
	friend info operator *(info a,info b){
		info c(a.n,b.m);
		for(int i=0;i<c.n;++i)
			for(int j=0;j<c.m;++j)
				for(int k=0;k<a.m;++k)
					c [i] [j] = (c [i] [j]+1ll*a [i] [k]*b [k] [j]%mo)%mo;
		return c;
	}
};

info Pow(info A,int c){
    info res(A.n,A.m);
    for(int i=0;i<res.n;++i) res[i][i]=1;
    for(;c;c>>=1,A=A*A) if(c&1) res=res*A;
    return res;
}

void Init(){
	n=read(),m=read(),mo=read();
	scanf("%s",s+1);
	for(int i=2,j=0;i<=m;++i){
		while(j&&s[i]!=s[j+1]) j=nex[j];
		if(s[i]==s[j+1]) ++j;
		nex[i]=j;
	}
}

void solve(){
	info a(m,m);
	for(int i=0;i<m;++i)
		for(char j='0';j<='9';++j){
			int k=i;
			while(k&&s[k+1]!=j) k=nex[k];
			if(s[k+1]==j) k++;
			if(k!=m) a[i][k]++;
		}
	info Ans(1,m),tmp=Pow(a,n);
	Years[0][0]=1;
	Ans=Ans*tmp;
	int sum=0;
	for(int i=0;i<m;++i)
		(sum+= Ans [0] [i])%= mo;
	printf("%d\n",sum);
}

int main(){Init();solve();return 0;}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325297259&siteId=291194637