POJ 1625 Censored!
发布时间:2020-12-14 03:37:32 所属栏目:大数据 来源:网络整理
导读:AC自动机 + DP + 大数。网上说矩阵过不去,写了一发样例都没调出来直接放弃了。由于习惯性的把数组开大了,爆了两次,然后直接A了。注意大数为0的输出 #includecstdio#includestring#includecstring#includecmath#includealgorithm#includeiostreamusing nam
AC自动机 + DP + 大数。网上说矩阵过不去,写了一发样例都没调出来直接放弃了。由于习惯性的把数组开大了,爆了两次,然后直接A了。注意大数为0的输出 #include<cstdio> #include<string> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> using namespace std; #define N 2005 #define INF 1000000009 typedef long long LL; int n; int letter[300]; struct Trie { Trie *fail; Trie *son[300]; int kind,isword; }s[N]; Trie *que[N]; int ptr; int id(unsigned char x){ return letter[x]; } Trie *NewNode(){ Trie *p = &s[ptr]; for(int i = 0; i < n; i++)p->son[i] = NULL; p->fail = NULL; p->isword = 0; p->kind = ptr++; return p; } void Insert(unsigned char *c,Trie *root){ Trie *tmp = root; for(int i = 0; c[i]; i++){ if(tmp->son[id(c[i])] == NULL) tmp->son[id(c[i])] = NewNode(); tmp = tmp->son[id(c[i])]; } tmp->isword = 1; } void Build_fail(Trie *root){ Trie *tmp; int head = 0,tail = 0; que[tail++] = root; root->fail = NULL; while(head < tail){ tmp = que[head++]; for(int i = 0; i < n; i++){ if(tmp->son[i]){ if(tmp == root)tmp->son[i]->fail = root; else { Trie *p = tmp->fail; while(p){ if(p->son[i]){ tmp->son[i]->fail = p->son[i]; break; } p = p->fail; } if(p == NULL)tmp->son[i]->fail = root; } if(tmp->son[i]->fail->isword)tmp->son[i]->isword = 1; que[tail++] = tmp->son[i]; } else if(tmp == root)tmp->son[i] = root; else tmp->son[i] = tmp->fail->son[i]; } } } #define length 100 class Bignum{ char s[length * 2]; public : Bignum(int x = 0){ memset(s,sizeof(s)); s[0] = x; } void setnum(int x){ for(int i = 0; x; i++){ s[i] = x % 10; x /= 10; } } Bignum operator+(Bignum x){ Bignum ans; for(int i = 0; i < length; i++){ ans.s[i] += s[i] + x.s[i]; ans.s[i + 1] += ans.s[i] / 10; ans.s[i] %= 10; } return ans; } void print(){ int i = length; while(s[i] == 0 && i >= 0)i--; if(i == -1)printf("0"); while(i >= 0)printf("%d",s[i--]); printf("n"); } }dp[55][105]; void solve(int tot){ dp[0][0].setnum(1); Bignum zero; for(int i = 1; i <= tot; i++){ for(int j = 0; j < ptr; j++){ Trie *tmp = &s[j]; if(tmp->isword)continue; for(int k = 0; k < n; k++){ if(tmp->son[k]->isword)continue; dp[i][tmp->son[k]->kind] = dp[i][tmp->son[k]->kind] + dp[i - 1][j]; } } } Bignum ans; for(int i = 0; i < ptr; i++){ ans = ans + dp[tot][i]; } ans.print(); } int main(){ int m,p; while(scanf("%d%d%d",&n,&m,&p) != EOF){ ptr = 0; Trie *root = NewNode(); unsigned char str[20]; unsigned char ms[55]; scanf("%s",ms); memset(letter,sizeof(letter)); for(int i = 0; ms[i]; i++) letter[ms[i]] = i; for(int i = 0; i < p; i++){ scanf("%s",str); Insert(str,root); } Build_fail(root); solve(m); } return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |