【KMP】HDU 6153 A Secret
来源:互联网 发布:sql应用开发培训 编辑:程序博客网 时间:2024/06/03 14:20
Problem Description
给你T组测试数据,每组测试数据,给你两个串,一个母串一个子串,让你求子串的所有后缀串,对于每个后缀串都和母串匹配,求出匹配次数,匹配次数*后缀串长度 求和 % 1000000007就是结果。
Sample Input
2
aaaaa
aa
abababab
aba
Sample Output
13
19
Hint
case 2:
Suffix(S2,1) = “aba”,
Suffix(S2,2) = “ba”,
Suffix(S2,3) = “a”.
N1 = 3,
N2 = 3,
N3 = 4.
L1 = 3,
L2 = 2,
L3 = 1.
ans = (3*3+3*2+4*1)%1000000007.
思路:
匹配问题,字符串很长,暴力是肯定过不了,所以转眼就去思考KMP。如果只是单单匹配一个后缀串,在主串出现的次数,这个还是很好解决的。所以思考点就是所有的后缀串在主串出现的次数,如何解决的问题。然后认真思考一下,就拿case2来说,如果aba匹配成功,那么是不是就代表ba匹配成功,a匹配成功。可这时aba匹配一次,ba匹配一次,a匹配了两次。该如何解决这个问题,防止重复计算,或者少计算。就是发现主串和子串都反转过来。这样匹配主串匹配到的子串也能匹配到,这样就很好的解决了上述问题,可是如果单单这样a只匹配了一次。aba的next[]数组是0,0,1。num[next[2] - 1] += num[2],这样我们就可以解决少计算的问题。详细还是得看代码。看了代码应该就理解为何这样做了。
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define N 1000055#define mod 1000000007int Next[N];//求next[]数组,我习惯以0为起始,-1也可以改一些东西就好了long long num[N];char s1[N], s2[N];void get_next(char s2[])//求next[]数组,不会的最好先去学习。对next[]数组用法要理解深点。{ int i, j = 0, len = strlen(s2); Next[j] = 0; for(i = 1; i < len; i++) { j = Next[i - 1]; while(j && s2[j] != s2[i]) j = Next[j - 1]; if(s2[j] == s2[i]) Next[i] = ++j; else Next[i] = 0; }}void KMP(char s1[], char s2[])//主串和最大后缀子串匹配{ int i = 0, j = 0, len1 = strlen(s1), len2 = strlen(s2); while(i < len1) { if(s1[i] == s2[j])//相等 { num[j]++;i++; j++;//num[j]++,记录匹配成功几次 } else { if(j == 0) i++; else j = Next[j - 1]; } if(j >= len2) { /*printf("%d\n", next[j - 1]);*/ j = Next[j - 1];//最大后缀子串匹配完了。j下标跳到(这 //个不知道怎么表达出来)和s2[j-1]一样字母的后面(这个后 //面不是简简单单的后面,自己画出来理解把)。 //从这里就可以看出num[next[2] - 1] += num[2]为什么这个式子了。 } }}int main(){ int T, i, len1, len2; scanf("%d", &T); while(T--) { scanf("%s %s", s1, s2); len1 = strlen(s1), len2 = strlen(s2); for(i = 0; i < len1 / 2; i++)//反转 swap(s1[i], s1[len1 - i - 1]); for(i = 0; i < len2 / 2; i++) swap(s2[i], s2[len2 - i - 1]); memset(num, 0, sizeof(num)); get_next(s2); KMP(s1, s2); long long ans = 0; for(i = len2 - 1; i >= 0; i--) { ans = (ans + num[i] * (i + 1) % mod) % mod; num[Next[i] - 1] += num[i];//累加 } printf("%lld\n", ans);//输出 } return 0;}
- hdu 6153 A Secret KMP
- HDU 6153 A Secret KMP
- HDU 6153 A Secret KMP
- Hdu 6153 A Secret【KMP】
- 【KMP】HDU 6153 A Secret
- HDU 6153 A Secret(KMP)
- hdu 6153 A Secret (kmp)
- hdu 6153 A Secret (KMP)
- hdu 6153 A Secret(KMP)
- hdu 6153 A Secret(KMP)
- HDU 6153 A secret(kmp)
- HDU 6153 A Secret【KMP||扩展KMP】
- hdu 6153 A Secret KMP&&扩展KMP
- HDU 6153-A Secret(kmp&&ccpc)
- HDU 6153 A Secret(KMP)
- HDU 6153 A Secret (扩展KMP)
- HDU 6153A Secret(kmp)
- HDU 6153 A Secret 经典扩展KMP
- 页面通信方式——跨文档消息传递XDM
- 【Noip2011】铺地毯
- 程序设计理论基础
- js和URL的传递、窗口的打开
- Oracle性能优化之统计分析
- 【KMP】HDU 6153 A Secret
- Android Studio 自带的模拟器 (avd模拟器)开机提示需要输入密码的问题
- 算法第1篇——选择排序
- Delphi下获取系统默认的UserAgent的方法
- 【LEDE】树莓派上玩LEDE终极指南-98-Node.js和NPM在LEDE上存在的问题和解决方案
- Visual Studio Code
- 爬今日头条文章
- 锁
- HDU2089 不要62