经典题目了....虽然只有一个不能出现的字符串,但还是写了ac自动机
1009: [HNOI2008]GT考试
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 2051 Solved: 1257
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位的数。 100%数据N<=10^9,M<=20,K<=1000 40%数据N<=1000 10%数据N<=6
Output
阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的结果.
Sample Input
4 3 100
111
Sample Output
81
HINT
Source
/* *********************************************** Author :CKboss Created Time :2015年05月12日 星期二 08时16分03秒 File Name :BZOJ1009.cpp ************************************************ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <cmath> #include <cstdlib> #include <vector> #include <queue> #include <set> #include <map> using namespace std; const int maxn=1200; int idx(char c) { return c-'0'; } int ch[maxn][11],fail[maxn],end[maxn]; int root,sz; char str[maxn]; int newnode() { memset(ch[sz],-1,sizeof(ch[sz])); end[sz++]=0; return sz-1; } void ac_init() { sz=0; root=newnode(); } void ac_insert(char str[]) { int len=strlen(str); int now=root; for(int i=0;i<len;i++) { int id=idx(str[i]); if(ch[now][id]==-1) ch[now][id]=newnode(); now=ch[now][id]; } end[now]++; } void ac_build() { queue<int> q; fail[root]=root; for(int i=0;i<10;i++) { if(ch[root][i]==-1) ch[root][i]=root; else { fail[ch[root][i]]=root; q.push(ch[root][i]); } } while(!q.empty()) { int now=q.front(); q.pop(); end[now]+=end[fail[now]]; for(int i=0;i<10;i++) { if(ch[now][i]==-1) ch[now][i]=ch[fail[now]][i]; else { fail[ch[now][i]]=ch[fail[now]][i]; q.push(ch[now][i]); } } } } int n,m,mod; typedef vector<int> vi; struct MATRIX { int _x,_y; int matrix[30][30]; MATRIX(){}; MATRIX(int n) { _x=_y=n; memset(matrix,0,sizeof(matrix)); } void getOne(int n) { for(int i=0;i<n;i++) matrix[i][i]=1; } MATRIX operator* (const MATRIX& b) const { int n=b._x; MATRIX ret(n); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { int temp=0; for(int k=0;k<n;k++) { temp=(temp+matrix[i][k]*b.matrix[k][j])%mod; } ret.matrix[i][j]=temp%mod; } } return ret; } }; MATRIX QuickPow(MATRIX M,int n) { MATRIX ans; ans.getOne(M._x); while(n) { if(n&1) ans=ans*M; M=M*M; n/=2; } return ans; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); scanf("%d%d%d",&n,&m,&mod); scanf("%s",str); ac_init(); ac_insert(str); ac_build(); MATRIX mat(sz); for(int i=0;i<sz;i++) { if(end[i]) continue; for(int j=0;j<10;j++) { int p=ch[i][j]; if(end[p]||end[fail[p]]) continue; mat.matrix[i][p]++; } } MATRIX ret=QuickPow(mat,n); int ans=0; for(int i=0;i<sz;i++) { ans=(ans+ret.matrix[0][i])%mod; } printf("%d\n",ans); return 0; }
时间: 2024-10-15 14:32:15