BZOJ 1009 GT考试
2015-01-15 13:45
141 查看
Description
阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字。他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为0Input
第一行输入N,M,K.接下来一行输入M位的数。 100%数据N<=10^9,M<=20,K<=1000 40%数据N<=1000 10%数据N<=6Output
阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的结果.Sample Input
4 3 100111
Sample Output
81HINT
Source
利用“不吉利数字”构建ac自动机(我好像小题大做了,一个串好像没有必要),构建初始矩阵,接着矩阵乘法即可。
初始矩阵a[i][j]表示走一步从i节点走到j节点的方案数。
code:
#include<vector> #include<queue> #include<cstring> #include<cstdio> #include<cstdlib> using namespace std; #define maxm 25 char buf[maxm]; int n,m,rhl,ans; struct node { int a[maxm*maxm][maxm*maxm],n,m; node() {memset(a,0,sizeof(a));n = m = 0;} friend node operator *(node x,node y) { node z; z.n = x.n; z.m = y.m; int i,j,k; for (i = 1;i <= z.n;++i) for (j = 1;j <= z.m;++j) for (k = 1;k <= x.m;++k) (z.a[i][j] += (long long)x.a[i][k]*(long long)y.a[k][j]%rhl)%=rhl; return z; } inline node quick(node x,int k) { node ret; ret.n = x.n; ret.m = x.m; for (int i = 1;i <= ret.n;++i) ret.a[i][i] = 1; for (;k;k>>=1,x = x*x) if (k & 1) ret = ret*x; return ret; } inline void calc() { for (int i = 0;i <= m;++i) (ans += a[1][i])%=rhl; } }s; struct trie { int next[maxm][10],fail[maxm],L,root; bool end[maxm]; inline int newnode() { memset(next[L],-1,sizeof(next[L])); return ++L-1; } inline void init() {L = 0; root = newnode();} inline void insert() { int len = strlen(buf),now = root,i; for (i = 0;i < len;++i) { if (next[now][buf[i]-'0'] == -1) next[now][buf[i]-'0'] = newnode(); now = next[now][buf[i]-'0']; } end[now] = true; } inline void build() { int now = root,i; queue <int> team; fail[root] = root; for (i = 0;i < 10;++i) if (next[now][i] == -1) next[now][i] = root; else fail[next[now][i]] = root,team.push(next[now][i]); while (!team.empty()) { now = team.front(); team.pop(); for (i = 0;i < 10;++i) if (next[now][i] == -1) next[now][i] = next[fail[now]][i]; else fail[next[now][i]] = next[fail[now]][i],team.push(next[now][i]); } } inline void ready() { vector <int> son[maxm]; queue <int> team; int i,now,v,nn; for (i = 0;i < L;++i) if (fail[i] != i) son[fail[i]].push_back(i); team.push(root); while (!team.empty()) { now = team.front(); team.pop(); nn = son[now].size(); for (i = 0;i < nn;++i) { v = son[now][i]; if (end[now]) end[v] = true; team.push(v); } } } inline void make() { int i,j; s.n = s.m = L; for (i = 0;i < L;++i) { if (end[i]) continue; for (j = 0;j < 10;++j) if (!end[next[i][j]]) s.a[i+1][next[i][j]+1]++; } } }ac; int main() { freopen("1009.in","r",stdin); freopen("1009.out","w",stdout); scanf("%d %d %d\n",&n,&m,&rhl); ac.init(); scanf("%s",buf); ac.insert(); ac.build(); ac.ready(); ac.make(); s = s.quick(s,n); s.calc(); printf("%d",ans); fclose(stdin); fclose(stdout); return 0; }
View Code
相关文章推荐
- BZOJ1009 [HNOI2008]GT考试
- GT考试(bzoj 1009)
- BZOJ 1009 [HNOI2008]GT考试 - KMP+计数DP+矩阵快速幂优化
- 【bzoj1009】[HNOI2008]GT考试
- 【BZOJ1009】【HNOI2008】GT考试
- 【BZOJ 1009】 [HNOI2008]GT考试
- Bzoj1009 [HNOI2008]GT考试
- BZOJ-1009-GT考试-HNOI2008
- BZOJ1009: [HNOI2008]GT考试
- BZOJ 1009 [HNOI2008]GT考试
- BZOJ 1009 [HNOI2008]GT考试 AC自动机+矩阵乘法
- [BZOJ1009][HNOI2008]GT考试
- GT考试 BZOJ 1009
- 【bzoj1009】[HNOI2008]GT考试
- 【BZOJ1009】【HNOI2008】GT考试
- BZOJ1009: [HNOI2008]GT考试
- BZOJ 1009: [HNOI2008]GT考试 AC自动机+矩阵快速幂
- [BZOJ 1009][HNOI2008]GT考试(KMP+线性齐次递推的矩阵加速?+DP)
- BZOJ1009: [HNOI2008]GT考试
- BZOJ-1009-GT考试-HNOI2008