BZOJ 1009: [HNOI2008]GT考试 AC自动机+矩阵快速幂

来源:互联网 发布:玻璃幕墙设计软件 编辑:程序博客网 时间:2024/05/30 04:14


经典题目了....虽然只有一个不能出现的字符串,但还是写了ac自动机

1009: [HNOI2008]GT考试

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 2051  Solved: 1257
[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位的数。 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

[Submit][Status][Discuss]


/* ***********************************************Author        :CKbossCreated 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;}


1 0
原创粉丝点击