ac自动机(dp)<AC自动机模板> ---高精度处理

来源:互联网 发布:java项目成果怎么写 编辑:程序博客网 时间:2024/06/05 01:04
#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>#include <string.h>#include <queue>#include <vector>   //poj1625  ac自动机(dp)---高精度处理(不能用矩阵乘法)using namespace std;int n, m, k, vis[200], dp[60][110][100];  //dp数组第一维表示单词长度,第二维表示到达什么节点(位置),第三维表示路径数目(用大数表示)struct node{int isword;int fail;int next[50];void init(){for(int t=0; t<50; ++t)next[t]=0;isword=0;fail=-1;}}a[110];void insert(char *p){int t, h, g=0, j=strlen(p);for(t=0; t<j; ++t){h=vis[p[t]-32];if(!a[g].next[h]){a[k].init();a[g].next[h]=k++;}g=a[g].next[h];}a[g].isword=1;return ;}void acAutomation()    //优化过的,可以当模板{int t, temp;queue<int> q;q.push(0);while(!q.empty()){int s=q.front();q.pop();for(t=0; t<n; ++t){if(a[s].next[t]==0){if(s==0)a[s].next[t]=0;else a[s].next[t]=a[a[s].fail].next[t];  //注意这里}else {temp=a[s].fail;if(s==0){a[a[s].next[t]].fail=0;}else {while(temp!=-1){if(a[temp].next[t]){a[a[s].next[t]].fail=a[temp].next[t];break;}temp=a[temp].fail;}if(temp==-1)a[a[s].next[t]].fail=0;}a[a[s].next[t]].isword|=a[a[a[s].next[t]].fail].isword;q.push(a[s].next[t]);}}}}void add(int *a1, int *b1)  //大数加法{int t, c=0;for(t=0; t<100; ++t){a1[t]=a1[t]+b1[t]+c;c=a1[t]/10;a1[t]%=10;}return ;}void solve(){int i, t, j, g;memset(dp, 0, sizeof(dp));dp[0][0][0]=1;for(i=1; i<=m; ++i)   //长度,类似矩阵一样(长度为m)就要m遍相加(矩阵就要m遍相乘){for(j=0; j<k; ++j){if(a[j].isword)continue;for(t=0; t<n; ++t){g=a[j].next[t];if(a[g].isword)continue;add(dp[i][g], dp[i-1][j]);   //dp状态转移dp[i][g]+=dp[i-1][j]只不过这里要对大数处理,所以用第三维来储存大数的没一个数字}}}int ans[100];memset(ans, 0, sizeof(ans));for(t=0; t<k; ++t)   //0包括哪些没有在字典树上的点(同样也有相同的长度m)的种类数{if(!a[t].isword)add(ans, dp[m][t]);}for(t=99; t>=0; --t){if(ans[t])break;}if(t<0)printf("0\n");else {while(t>=0){printf("%d", ans[t]);t--;}printf("\n");}return ;}int main(){int d, t, j, g;char p[60];while(scanf("%d%d%d", &n, &m, &d)!=EOF){a[0].init();k=1;scanf("%s", p);j=strlen(p);for(t=g=0; t<j; ++t){vis[p[t]-32]=g++;   //vis表示不同字母的序号}for(t=0; t<d; ++t){scanf("%s", p);insert(p);}acAutomation();solve();}return 0;}

0 0
原创粉丝点击