BZOJ1030 [JSOI2007]文本生成器(AC自动机+dp)
2015-06-24 18:09
218 查看
【题解】
与poj2778有类似之处,只不过本题模板串太长,无法用到矩阵,而文本较短,适于dp
ans = 26^m - 不含任意单词的文本数
不含任意单词的文本数 的求法:
转化成从有向图的一点出发,走n步到达另一结点的方案数
本题为 从字典树的root出发,走m步到达任一结点,且不构成单词 的方案数,需使建立的所有有向边合法(无法走出单词)
将单词建成AC自动机,每个结点u都连向 它的26个后继ch[u][i],或它在fail树上的祖先的后继ch[fa][i],使用改进过的AC自动机,就可以统一写成ch[u][i]
然后标记所有词尾结点,及失配指针指向词尾结点的点,以后用到路径时不考虑含有这些点的边
若结点少的话,就求出图对应的邻接矩阵A,然后用快速幂求A^m
否则,设f[i][j]表示用i步能从root走到j的方案数,按照点之间同样的连接关系转移,按步数从小到大做dp就行了
【代码】
与poj2778有类似之处,只不过本题模板串太长,无法用到矩阵,而文本较短,适于dp
ans = 26^m - 不含任意单词的文本数
不含任意单词的文本数 的求法:
转化成从有向图的一点出发,走n步到达另一结点的方案数
本题为 从字典树的root出发,走m步到达任一结点,且不构成单词 的方案数,需使建立的所有有向边合法(无法走出单词)
将单词建成AC自动机,每个结点u都连向 它的26个后继ch[u][i],或它在fail树上的祖先的后继ch[fa][i],使用改进过的AC自动机,就可以统一写成ch[u][i]
然后标记所有词尾结点,及失配指针指向词尾结点的点,以后用到路径时不考虑含有这些点的边
若结点少的话,就求出图对应的邻接矩阵A,然后用快速幂求A^m
否则,设f[i][j]表示用i步能从root走到j的方案数,按照点之间同样的连接关系转移,按步数从小到大做dp就行了
【代码】
#include<stdio.h> #include<stdlib.h> #include<string.h> #define MOD 10007 int ch[6005][30],no[6005],f[6005],q[6005],dp[105][6005]; char s[105]; int sz=0; void tj() { int i,u=0,len=strlen(s); for(i=0;i<len;i++) { if(ch[u][s[i]-64]==0) ch[u][s[i]-64]=++sz; u=ch[u][s[i]-64]; } no[u]=1; } void build() { int i,head=0,tail=0,u,v; for(i=1;i<=26;i++) if(ch[0][i]>0) q[tail++]=ch[0][i]; while(head<tail) { u=q[head++]; no[u]|=no[f[u]]; for(i=1;i<=26;i++) { v=ch[u][i]; if(v>0) { f[v]=ch[f[u]][i]; q[tail++]=v; } else ch[u][i]=ch[f[u]][i]; } } } int main() { int n,m,i,j,k,ans=0,ans2=1; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { scanf("%s",s); tj(); } build(); dp[0][0]=1; for(i=1;i<=m;i++) { for(j=0;j<=sz;j++) if(no[j]==0&&dp[i-1][j]>0) for(k=1;k<=26;k++) dp[i][ch[j][k]]=(dp[i][ch[j][k]]+dp[i-1][j])%MOD; } for(i=0;i<=sz;i++) if(no[i]==0) ans+=dp[m][i]; for(i=1;i<=m;i++) ans2=(ans2*26)%MOD; printf("%d",((ans2-ans)%MOD+MOD)%MOD); return 0; }
相关文章推荐
- JS中字符串转化与日期的相互转化及比较时间先后
- GridView其实是一个table,这里使用js循环table,代码如下:
- JavaScript高阶函数
- js怎么获取图片的相对地址
- js实现仿阿里巴巴城市选择框效果实例
- js实现文本框提示
- Javascript常用小技巧汇总
- JavaScript类属性
- Notepad++中轻松转成json格式AND自动安装json view 插件
- 【JavaScript】程序入门(二)
- JS动态增加页面上的控件实例
- js 的try catch应用
- call
- js实现的倒计时按钮实例
- JavaScript实现通过的集合类
- #笔记#圣思园 JavaWeb 第46讲——JavaScript脚本语言
- js实现大转盘抽奖游戏实例
- JSONViewer Notepad++ plugin安装
- 字符串集合或字符串数组转换成json数组
- JS中的prototype