BZOJ1030 JSOI2007 文本生成器 题解&代码
2016-03-11 16:30
519 查看
题意:给出n个匹配串,询问:对于长度为m的串,有多少个串至少包含一个匹配串(答案对10007取模)
题解:
“至少包含一个匹配串的长度为m的串”,那么很容易转化为“所有串除去不包含任何匹配串的长度为m的串”
然后就是喜闻乐见的AC自动机上的dp了,dp方程显然是dp[i][j]表示长度为i的串匹配到j位时有多少不包含任何匹配串
有:dp[i][ch[j][k]]+=dp[i-1][j]
即孩子节点一定由有效父亲节点推知(节点本身flag指针就是true的当然是0)
题解:
“至少包含一个匹配串的长度为m的串”,那么很容易转化为“所有串除去不包含任何匹配串的长度为m的串”
然后就是喜闻乐见的AC自动机上的dp了,dp方程显然是dp[i][j]表示长度为i的串匹配到j位时有多少不包含任何匹配串
有:dp[i][ch[j][k]]+=dp[i-1][j]
即孩子节点一定由有效父亲节点推知(节点本身flag指针就是true的当然是0)
/************************************************************** Problem: 1030 User: Rainbow6174 Language: C++ Result: Accepted Time:76 ms Memory:4396 kb ****************************************************************/ #include <iostream> #include <cstdio> #include <cstring> #define MOD 10007 using namespace std; const int maxt = 6005; int n, m, tot, ans = 1, temp, ch[maxt][26], fail[maxt], q[maxt], dp[105][maxt]; char s[105]; bool flag[maxt]; void newnode(int x, int v) { ch[x][v]=++tot; } void addtrie(char s[]) { int x = 0, p = 0, len = strlen(s); while( p < len ) { temp = s[p]-'A'; if ( !ch[x][temp] ) newnode(x, temp); x = ch[x][temp]; p++; } flag[x] = 1; } void AC(void) { int h = 0, t = 0; for(int i = 0; i < 26; i++) if(ch[0][i]) q[t++] = ch[0][i]; while( h < t ) { temp = q[h++]; for(int i = 0; i < 26; i++) if( !ch[temp][i] ) ch[temp][i] = ch[fail[temp]][i]; else fail[ch[temp][i]] = ch[fail[temp]][i], flag[ch[temp][i]] |= flag[fail[ch[temp][i]]], q[t++] = ch[temp][i]; } } int main(void) { scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) { scanf("%s", s); addtrie(s); } AC(); dp[0][0] = 1; for(int i = 1; i <= m; i++) { for(int j = 0; j <= tot; j++) { if(flag[j] || !dp[i-1][j]) continue; for(int k = 0; k < 26; k++) { dp[i][ch[j][k]] += dp[i-1][j]; dp[i][ch[j][k]] %= MOD; } } ans*=26; ans%=MOD; } //cout<<ans<<endl; for(int i = 0; i <= tot; i++) { //cout<<i<<' '<<flag[i]<<endl; if(!flag[i]) { //cout<<dp[m][i]<<endl; ans -= dp[m][i]; ans += MOD; ans %= MOD; } } printf("%d\n",ans); return 0; }
相关文章推荐
- js中,销魂的this
- 封装JS文件到DLL中并在页面中调用
- js常用模板引擎
- js--冒泡排序[由小到大]
- js 解决原型问题的方案 : 构造器和原型的组合
- js事件绑定的几种方式
- js模拟表单提交
- 举例说明JavaScript中的实例对象与原型对象
- js之widget日历datepicker
- JavaScript中setTimeout和setInterval函数的传参及调用
- js动态加载html,加载后的页面元素某些事件失效的解决方案
- javascript中面向对象之原型链解析
- 原生JavaScript制作微博发布面板效果
- 关于javascript的this指向问题
- javascript日常总结
- 深入学习JavaScript(一)
- [RxJS] Completing a Stream with TakeWhile
- (一)ExtJs学习前的准备工作,及第一个Ext小例子HelloWorld
- [RxJS] Adding Conditional Logic with Filter
- json 和jsonp