bzoj 1030
2015-08-06 17:34
260 查看
AC自动机模板
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <string> #include <map> #include <vector> #include <stack> #include <queue> #include <utility> #include <iostream> #include <algorithm> template<class Num>void read(Num &x) { char c; int flag = 1; while((c = getchar()) < '0' || c > '9') if(c == '-') flag *= -1; x = c - '0'; while((c = getchar()) >= '0' && c <= '9') x = (x<<3) + (x<<1) + (c-'0'); x *= flag; return; } template<class Num>void write(Num x) { if(x < 0) putchar('-'), x = -x; static char s[20];int sl = 0; while(x) s[sl++] = x%10 + '0',x /= 10; if(!sl) {putchar('0');return;} while(sl) putchar(s[--sl]); } const int maxn = 105, maxl = 105, size = 26, Mod = 10007; struct TrieNode { TrieNode *p[size], *fail; bool end; int dp[maxl]; }T[maxn*maxl], *root; int n, m, tot; char c[maxl]; TrieNode *NewNode() { return T + (++tot); } void insert(char *t,TrieNode *now) { if(!(*t)) { now->end = true; return; } TrieNode *&next = now->p[(*t)-'A']; if(!next) next = NewNode(); insert(t + 1, next); } void init() { read(n), read(m); root = NewNode(); for(int i = 1; i <= n; i++) { scanf("%s",c); insert(c, root); } } void build() { std::queue<TrieNode*>line; root->fail = root; for(int i = 0; i < size; i++) if(root->p[i]) { root->p[i]->fail = root; line.push(root->p[i]); } else root->p[i] = root; while(!line.empty()) { TrieNode *x = line.front(); line.pop(); for(int i = 0; i < size; i++) { if(x->p[i]) { x->p[i]->fail = x->fail->p[i]; line.push(x->p[i]); } else x->p[i] = x->fail->p[i]; } if(x->fail->end) x->end = true; } } void update(int len) { for(int x = 1; x <= tot; x++) for(int i = 0; i < size; i++) if(!T[x].p[i]->end) { T[x].p[i]->dp[len] += T[x].dp[len-1]; T[x].p[i]->dp[len] %= Mod; } } long long getans() { long long ans = 0, sum = 1; for(int i = 1; i <= tot; i++) ans += T[i].dp[m], ans %= Mod; for(int i = 1; i <= m; i++) sum *= size, sum %= Mod; ans = (sum - ans + Mod)%Mod; return ans; } int main() { #ifndef ONLINE_JUDGE freopen("1030.in","r",stdin); freopen("1030.out","w",stdout); #endif init(), build(); root->dp[0] = 1; for(int i = 1; i <= m; i++) update(i); write(getans()); #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); #endif return 0; }
相关文章推荐
- Xamarin安装和跳坑指南
- iOS 导航栏返回按钮时间action获取
- Java程序设计之算出一年第多少天
- bzoj 1030 分类: bzoj templates 2015-08-06 17:34 10人阅读 评论(0) 收藏
- 【Thinking in Java】编写构造器时应注意:尽量避免调用其他非private方法
- VB-控件注册 - 利用资源文件将dll、ocx打包进exe文件
- 短信验证
- 浏览器 猛犸
- 公用方法Store
- pickle模块的基本使用
- 工具资源网站
- poj-1094 Sorting It All Out
- Android 图片内存溢出处理笔记
- Android 蓝牙设备的开启与关闭功能的实现
- android优化工具
- Redis集群主备模式部署
- 深入理解C语言(转载)
- POJ 1236 Network of Schools(强连通分量缩点求根节点和叶子节点的个数)
- android:showAsAction="always|withText"分析
- Keychain的简单使用