bzoj3620 似乎在梦中见过的样子 kmp暴力
2016-03-18 19:56
288 查看
这道题目感觉上好像是可以用SA过掉的。。但是看一下N15000然后Statue里面一个个都6000+ms,翻了一下题解发现是kmp暴力。
打了一半发现不会然后回去看题目,发现位置相同但是结构不懂的子串只算一次!!!这大概就是为什么不能用SA的原因吧。。不过这样kmp就好写多了。
首先枚举头结点i,同kmp构造S[i,n]的失配函数,然后我们发现对于一个右端点j能更新答案当且仅当存在一个节点x,是j的失配指针上的某一个祖先(就是可以从j通过失配指针走到x),满足k<(i+j)/2且x-i+1>=k,也就是可以以[i,x]为A,[x+1,j-(x-i)]为B(+1-1的什么没有细考错了请指出)。于是可以用一个辅助数组g[j]表示满足x-i+1>=k的x中最小的x,当然如果fail[j]-i+1<k那么g[j]=j(fail[]为失配指针)。
AC代码如下:
by lych
2016.3.18
打了一半发现不会然后回去看题目,发现位置相同但是结构不懂的子串只算一次!!!这大概就是为什么不能用SA的原因吧。。不过这样kmp就好写多了。
首先枚举头结点i,同kmp构造S[i,n]的失配函数,然后我们发现对于一个右端点j能更新答案当且仅当存在一个节点x,是j的失配指针上的某一个祖先(就是可以从j通过失配指针走到x),满足k<(i+j)/2且x-i+1>=k,也就是可以以[i,x]为A,[x+1,j-(x-i)]为B(+1-1的什么没有细考错了请指出)。于是可以用一个辅助数组g[j]表示满足x-i+1>=k的x中最小的x,当然如果fail[j]-i+1<k那么g[j]=j(fail[]为失配指针)。
AC代码如下:
#include<iostream> #include<cstdio> #include<cstring> #define N 20005 using namespace std; int n,m,f ,g ; char ch ; int main(){ scanf("%s",ch+1); n=strlen(ch+1); scanf("%d",&m); int i,j,k,ans=0; for (i=1; i<=n-(m<<1); i++){ f[i]=k=i-1; g[i]=i; for (j=i+1; j<=n; j++){ while (k!=i-1 && ch[j]!=ch[k+1]) k=f[k]; if (ch[j]==ch[k+1]) k++; f[j]=k; g[j]=(k<i+m-1)?j:g[k]; if (g[j]<((i+j)>>1)) ans++; } } printf("%d\n",ans); return 0; }
by lych
2016.3.18
相关文章推荐
- RHEL 7.0 yum源
- 89.数字三角形
- Codeforces Beta Round #4 (Div. 2 Only) D. Mysterious Present 记忆化搜索
- winform下的简易播放器
- IOS控件学习之UI ScrollView(7)
- 浅谈ios异步加载
- 【初级C语言】简单的程序设计案例
- GRID-颜色移上去的变化
- JAVA GUI界面组件学习
- poj2438 哈密顿图
- CentOS7.2共享文件夹_安装配置SAMBA服务器
- Eclipse 乱码 解决方案总结(UTF8 -- GBK)
- Improved SLIC 算法学习笔记
- #pg学习#postgresql的安装
- 常见http状态码详解
- MyBatis初级环境搭建
- hdu1754线段树单点更新
- C:数据结构与算法之顺序表
- 蓝桥杯 历届试题 大数乘法
- Lintcode 用栈实现队列