BZOJ 1009: [HNOI2008]GT考试

1009: [HNOI2008]GT考试

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 3434  Solved: 2109
[Submit][Status][Discuss]

Description

  阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字。
他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为
0

Input

  第一行输入N,M,K.接下来一行输入M位的数。 N<=10^9,M<=20,K<=1000

Output

  阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的结果.

Sample Input

4 3 100
111

Sample Output

81

HINT

 

Source

分析:

 我们可以想到这题可以用$DP$来完成,$f[i][j]$代表构造方案的第$i$个字符匹配上了不吉利数字的第$j$个字符的合法方案数,然后我们枚举下一位填哪个数字转移到哪里,如果我们枚举的数字$k$恰好匹配上了第$j+1$个不吉利数字,那么就可以转移到$f[i+1][j+1]$,否则我们就通过$kmp$来找到转移的状态...

发现不吉利数字的长度很小,方案数字的长度很大,所以可以用矩阵快速幂来优化转移...

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
using namespace std;

const int maxn=20+5;

int n,m,mod,nxt[maxn];

char s[maxn];

struct Matrix{
	
	int a[maxn][maxn];
	
	inline void clear(void){
		memset(a,0,sizeof(a));
	}
	
	friend Matrix operator * (Matrix x,Matrix y){
		Matrix ans;ans.clear();
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
					(ans.a[i][j]+=(x.a[i][k]*y.a[k][j])%mod)%=mod;
		return ans;
	}
	
	inline Matrix power(Matrix M,int x){
		Matrix ans;ans.clear();
		for(int i=0;i<n;i++)
			ans.a[i][i]=1;
		while(x){
			if(x&1)
				ans=ans*M;
			M=M*M,x>>=1;
		}
		return ans;
	}
	
}G;

inline void getnxt(void){
	nxt[0]=nxt[1]=0;int k;
	for(int i=1;i<n;i++){
		k=nxt[i];
		while(k&&s[i+1]!=s[k+1])
			k=nxt[k];
		if(s[i+1]==s[k+1])
			nxt[i+1]=k+1;
		else
			nxt[i+1]=0;
	}
}

inline void getmatrix(void){
	for(int i=0;i<n;i++)
		for(int j=0,k;j<=9;j++){
			k=i;
			while(k&&(int)(s[k+1]-'0')!=j)
				k=nxt[k];
			if((int)(s[k+1]-'0')==j)
				k++;
			else
				k=0;
			G.a[i][k]++;
		}
}

inline int solve(void){
	G=G.power(G,m);
	int ans=0;
	for(int i=0;i<=n;i++)
		(ans+=G.a[0][i])%=mod;
	return ans;
}

signed main(void){
	scanf("%d%d%d%s",&m,&n,&mod,s+1);G.clear();
	getnxt();getmatrix();printf("%d\n",solve());
	return 0;
}

  


By NeighThorn

posted @ 2017-02-17 14:50  NeighThorn  阅读(190)  评论(2编辑  收藏  举报