<kmp>codevs 1404 字符串匹配
2017-10-09 16:21
302 查看
题面传送门
以为是kmp的裸题(其实差不多233),结果调了半天,后来搜了题解才知道要怎么改。
在kmp算法的过程中,如果在每循环到i时,记ans[p]++。这个数组代表的意义是:到字符串A的第i个字符的最大匹配长度。但是,对于ans[nxt[p]],我们却没有作记录。所以在最后处理ans函数时,先倒序处理一遍(一定要倒序),这样才能累加。这样子处理出来的ans数组代表大于等于它的所有答案,最后的答案就是ans[x]-ans[x+1],所以再处理一遍ans数组就可以了。
注意:倒序循环时,不能循环到0,否则就会重复累加
代码:
以为是kmp的裸题(其实差不多233),结果调了半天,后来搜了题解才知道要怎么改。
在kmp算法的过程中,如果在每循环到i时,记ans[p]++。这个数组代表的意义是:到字符串A的第i个字符的最大匹配长度。但是,对于ans[nxt[p]],我们却没有作记录。所以在最后处理ans函数时,先倒序处理一遍(一定要倒序),这样才能累加。这样子处理出来的ans数组代表大于等于它的所有答案,最后的答案就是ans[x]-ans[x+1],所以再处理一遍ans数组就可以了。
注意:倒序循环时,不能循环到0,否则就会重复累加
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=200000+10; char A[maxn],B[maxn]; int n,m,k,x; int ans[maxn],nxt[maxn]; void make_nxt() { for(int i=1;i<m;++i) { int p=nxt[i]; while(p&&B[i+1]!=B[p+1]) p=nxt[p]; if(B[i+1]==B[p+1]) p++; nxt[i+1]=p; } } void kmp() { int p=0; for(int i=1;i<=n;++i) { while(p&&B[p+1]!=A[i]) p=nxt[p]; if(A[i]==B[p+1]) ++p; ans[p]++; } } int main() { scanf("%d%d%d",&n,&m,&k); scanf("%s\n%s",A+1,B+1); make_nxt(); kmp(); for(int i=m;i>0;--i) ans[nxt[i]]+=ans[i]; for(int i=0;i<=m;++i) ans[i]-=ans[i+1]; for(int i=1;i<=k;++i) { scanf("%d",&x); printf("%d\n",ans[x]); } return 0; }
相关文章推荐
- 【codevs1404】字符串匹配 KMP
- CODE[VS] 1404 字符串匹配
- 字符串匹配(codevs 1404)
- CODEVS——T 1404 字符串匹配
- [codeVS1404] 字符串匹配
- <线段树系列3> codevs 1082 线段树练习3
- <矩阵快速幂>codevs 3332 数列
- <线段树系列4> codevs 4927 线段树练习5
- <状压DP>codevs 2451 互不侵犯
- <C/C++算法>字符串匹配---KMP算法
- <线段树版>codevs 3304 水果姐逛水果街Ⅰ
- <背包DP>codevs 1684 垃圾陷阱
- CodeVS1404 字符串匹配(扩展kmp)
- Codevs 1404 字符串匹配(Kmp)
- <DP>codevs 2189 数字三角形w
- <序列DP>codevs 4748 低价购买
- <二分答案+spfa验证>codevs 1183 泥泞的道路
- 字符串匹配算法之BF vs KMP
- <倍增lca>codevs 3305 水果姐逛水果街Ⅱ
- <考试题> codevs 5440 运输计划 (二分+lca+dfs序+树上差分)