hdu 3336 kmp+next数组应用

分析转自:http://972169909-qq-com.iteye.com/blog/1114968

十分易懂

题意:求字串中【前缀+跟前缀相同的子串】的个数?

Sample Input

1

4

abab

Sample Output

6

abab:包括2个a,2个ab,1个aba,1个abab

这里要用到next值的意义:

next[i]表示前i个字符所组成的字符串的最大前后缀匹配长度

举个例子:

next[5]=2, 表示下标5前面那个字符串abcab的前后缀匹配的最大长度是2,显然就是ab了

回到本题:

所求=字串的前缀个数+与前缀相同的子串

问题可以部分转化为:每个前缀的最大前后缀匹配问题

继续用上面的例子:

第一步:

对于这段子串,next[5]=2,然后后面不符合next值的递推规律了

所以对于abcab,长度为2的后缀,即ab与前缀匹配

所以+1个ab,注意还要+1个a,既然后缀ab跟前缀ab匹配,则必有a跟前缀匹配

也就是+2个了,其实实际上+next[5]就可以了,因为这是最长前后缀匹配长度

第二步:

对于这段子串:

next[6]=1,然后后面不符合next值的递推规律了

所以对于abcaba,长度为1的后缀,即a与前缀匹配

所以+1个a,也就是+next[6]了

第三步:

对于整个串:

next[12]=4后面没有了

所以对于整个串:abcabacbabca,长度为4的后缀跟前缀匹配

所以+1个abca,+1个abc,+1个ab,+1个a,总共+4个,也就是+next[12]了

最后:

好了,刚刚一共+了7个与前缀匹配的子串

上面说了题目是求:字串的前缀个数+与前缀相同的子串个数

与前缀相同的子串个数就是7个了

然后字串的前缀个数当然就是整个串的长度了,那么就是12个

加起来就是答案:19

 1 #include<stdio.h>
 2 #include<string.h>
 3 const int MAXN=200020;
 4 const int MOD=10007;
 5 int dp[MAXN];
 6 char str[MAXN];
 7 int next[MAXN];
 8
 9 void getNext(char *p)
10 {
11     int j,k;
12     j=0;
13     k=-1;
14     next[0]=-1;
15     int len=strlen(p);
16     while(j<len)
17     {
18         if(k==-1||p[j]==p[k])
19         {
20             j++;
21             k++;
22             next[j]=k;
23         }
24         else k=next[k];
25     }
26 }
27 int main()
28 {
29     int T;
30     int n;
31     scanf("%d",&T);
32     while(T--)
33     {
34         scanf("%d",&n);
35         scanf("%s",&str);
36         getNext(str);
37         dp[0]=0;
38         int ans=0;
39         for(int i=1;i<=n;i++)
40         {
41             dp[i]=dp[next[i]]+1;
42             dp[i]%=MOD;
43             ans+=dp[i];
44             ans%=MOD;
45         }
46         printf("%d\n",ans);
47     }
48     return 0;
49 }
时间: 2024-11-09 21:43:18

hdu 3336 kmp+next数组应用的相关文章

HDU 3336 (KMPnext数组的应用)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3336 题意:求给定字符串的前缀出现次数的总和. 题解:先求得next数组,从i=1开始遍历next数组,只要其值不为0,则让计数器加1,原因:next数组每出现不为0的时候,则代表有个一个前缀重复. 最后再把计数器加n,原因:n个前缀没有算进去. 代码如下: 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring>

hdu 1358 KMP next数组的运用

题意:给一个字符串,从第二个字符开始,判断前面的是不是循环串,是的话就输出当前位置和循环次数. 考的是对于next数组的理解和灵活运用,字符编号从0开始,那么if(i%(i-next[i])==0),则i前面的串为一个循环串,其中循环子串出现i/(i-next[i])次. 1 #include<iostream> 2 #include<string> 3 #include<string.h> 4 #define MAX_N 1000005 5 6 using names

HDU 3336 (KMP next性质) Count the string

直接上传送门好了,我觉得他分析得非常透彻. http://972169909-qq-com.iteye.com/blog/1114968 1 #include <cstdio> 2 #include <cstring> 3 4 const int maxn = 200000 + 10; 5 const int MOD = 10007; 6 char s[maxn]; 7 int next[maxn], l; 8 9 void get_next() 10 { 11 int k = -

hdu 3336 Count the string(KMP)

一道应用kmp算法中next数组的题目 这其中vis[i]从1加到n vis[i]=[next[i]]+1; #include<string.h> #include<stdlib.h> #include<stdio.h> #include<iostream> #include<algorithm> using namespace std; char s[200005]; int b; int next[200005]; int vis[20000

[kuangbin带你飞]专题十六 KMP &amp; 扩展KMP &amp; ManacherK - Count the string HDU - 3336(前缀数量问题)

K - Count the string HDU - 3336 题目链接:https://vjudge.net/contest/70325#problem/K 题目: It is well known that AekdyCoin is good at string problems as well as number theory problems. When given a string s, we can write down all the non-empty prefixes of t

HDU 3336(kmp+dp

hdu 3336(说实话理解得马马虎虎...) 题目:给出一个字符串,问该字符串的每个前缀在字符串中出现的次数之和. 思路:需要对next数组有足够的理解.设dp[i]表示以i结尾的字符串中出现的总次数(答案),那么首先在next[i]到i之间的前缀不会是对应的后缀,所以该长度的串数量恰好是dp[next[i]]+1. /* * @author: Cwind */ //#pragma comment(linker, "/STACK:102400000,102400000") #incl

hdu 3336 Count the string

Count the stringTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4239    Accepted Submission(s): 1977 Problem Description It is well known that AekdyCoin is good at string problems as well as num

hdu 3333 树状数组+离线处理

http://acm.hdu.edu.cn/showproblem.php?pid=3333 不错的题,想了很久不知道怎么处理,而且答案没看懂,然后找个例子模拟下别人的代码马上懂了---以后看不懂的话就拿个例子模拟下别人的代码 举个例子:1 3 3 5 3 5 查询 a, 2 4 b, 2 5 最初是这么想的:对于a查询,倘若把第二个数第三个数变成1个3,那么到b查询,又出现了两个3,再做处理似乎还是O(n),而且如果先出现2,5查询,后出现2,4查询,那么还需要把删除的数补回来.....o(╯

Hdu 3887树状数组+模拟栈

题目链接 Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1757    Accepted Submission(s): 582 Problem Description You are given a tree, it’s root is p, and the node is numbered fr