BZOJ4327 : JSOI2012 玄武密码
2015-11-21 01:35
537 查看
对所有询问串建立AC自动机。
然后将母串在AC自动机上跑,每走到一个点x,从x点出发沿着fail指针能到的所有前缀都是匹配成功的,暴力向上走,碰到走过的就break,这样每个点最多只会被标记一次。
时间复杂度$O(N+100M)$。
然后将母串在AC自动机上跑,每走到一个点x,从x点出发沿着fail指针能到的所有前缀都是匹配成功的,暴力向上走,碰到走过的就break,这样每个点最多只会被标记一次。
时间复杂度$O(N+100M)$。
#include<cstdio> #include<cstring> const int N=10000003,M=100010; int tot,son [4],f ,fail ,q ;bool v ; int n,m,i,fin[M],len[M];char a ,b[103]; inline int id(char x){ if(x=='S')return 0; if(x=='E')return 1; if(x=='W')return 2; return 3; } inline void insert(int p){ int l=len[p]=strlen(b),x=0,i=0,w; for(;i<l;x=son[x][w],i++)if(!son[x][w=id(b[i])])f[son[x][w]=++tot]=x; fin[p]=x; } void make(){ int h=1,t=0,i,x;fail[0]=-1; for(i=0;i<4;i++)if(son[0][i])q[++t]=son[0][i]; while(h<=t)for(x=q[h++],i=0;i<4;i++)if(son[x][i])fail[q[++t]=son[x][i]]=son[fail[x]][i];else son[x][i]=son[fail[x]][i]; } void solve(){ for(int x=0,i=0,w;i<n;i++){ x=son[x][w=id(a[i])]; for(int y=x;~y;y=fail[y])if(v[y])break;else v[y]=1; } } inline int ask(int p){ for(int x=fin[p],y=len[p];y;y--,x=f[x])if(v[x])return y; return 0; } int main(){ scanf("%d%d%s",&n,&m,a); for(i=0;i<m;i++)scanf("%s",b),insert(i); make(); solve(); for(i=0;i<m;i++)printf("%d\n",ask(i)); return 0; }
相关文章推荐
- 【JS关键字】
- ExtJS4.2学习(14)基于表格的扩展插件(2)(转)
- 学习日记:json之what,why,where,how及应用
- js原生封装自定义滚动条
- ExtJS4.2学习(13)基于表格的扩展插件---rowEditing
- webpack bable-loader升级无法编译jsx es6
- javascript实现Email邮件显示与删除功能
- JavaScript实现自动生成网页元素功能(按钮、文本等)
- js实现索引图片切换效果
- javascript实现动态统计图开发实例
- 超详细的javascript数组方法汇总
- 分享经典的JavaScript开发技巧
- js if
- js 参数带0丢失的问题
- JS如何获取多个相同class标签并分别再输出各自的文本
- 转: JSP中include指令和include动作的区别
- 使用js获取表单form的数据
- JavaScript实现点击按钮弹出输入框,点确定后添加li组件到ul组件里
- javascript eval函数用法一例
- How to invoke a JSF managed bean on a HTML DOM event using native JavaScript?