【KMP】HDU 6153 A Secret
2017-08-21 09:16
393 查看
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],这样我们就可以解决少计算的问题。详细还是得看代码。看了代码应该就理解为何这样做了。
给你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 1000000007 int Next ;//求next[]数组,我习惯以0为起始,-1也可以改一些东西就好了 long long num ; char s1 , s2 ; 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||扩展kmp)
- hdu 6153 A Secret(kmp||扩展kmp)
- HDU 6153 A secret(kmp)
- hdu 6153 A Secret(kmp||扩展kmp)
- HDU 6153 A Secret(扩展KMP)
- HDU 6153 A Secret【KMP||扩展KMP】
- hdu 6153 A Secret(kmp||扩展kmp)
- hdu 6153 A Secret (kmp)
- HDU 6153 A Secret kmp || extkmp
- 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】
- hdu 6153 A Secret(kmp||扩展kmp)
- HDU-6153 A Secret (扩展KMP)
- hdu 6153 A Secret【KMP/想法题】
- hdu 6153 A Secret(kmp||扩展kmp)