题目网址:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=110060#problem/A
Description
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 this string. For example:
s: " abab"
The prefixes are: "a", " ab", " aba", " abab"
For each prefix, we can count the times it matches in s. So we can see that prefix "a" matches twice, " ab" matches twice too, " aba" matches once, and " abab" matches once. Now you are asked to calculate the sum of the match times for all the prefixes. For " abab", it is 2 + 2 + 1 + 1 = 6.
The answer may be very large, so output the answer mod 10007.
s: " abab"
The prefixes are: "a", " ab", " aba", " abab"
For each prefix, we can count the times it matches in s. So we can see that prefix "a" matches twice, " ab" matches twice too, " aba" matches once, and " abab" matches once. Now you are asked to calculate the sum of the match times for all the prefixes. For " abab", it is 2 + 2 + 1 + 1 = 6.
The answer may be very large, so output the answer mod 10007.
adfsa
Input
The first line is a single integer T, indicating the number of test cases.
For each case, the first line is an integer n (1 <= n <= 200000), which is the length of string s. A line follows giving the string s. The characters in the strings are all lower-case letters.
For each case, the first line is an integer n (1 <= n <= 200000), which is the length of string s. A line follows giving the string s. The characters in the strings are all lower-case letters.
Output
For each case, output only one number: the sum of the match times for all the prefixes of s mod 10007.
Sample Input
1 4 abab
Sample Output
6
题意: 给一个字符串,求这个字符串的所有前缀在字符串中出现的次数和。
思路: 使用next[]跳转表,已经有了next数组,next[i]=k表示最大的j使得0~k-1==i-k+1~i,因此,对于样例abab,则有
0 1 2 3
s[] a b a b
p[] 0 0 1 2
对于4个前缀:
a
ab
aba
abab
设dp[i]表示子串s[0~i]共含有以s[i]为结尾的前缀的数目,则以s[i]结尾的前缀数就是自己本身加上以s[p[i]]结尾的前缀数,也就是例如i=2
则有:p[i]=1,dp[i]=dp[p[i]-1]+1 ;
a
aba这两个前缀,其中a就是s[p[i]]结尾的前缀。
本题代码:
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> using namespace std; char s[200005]; int p[200005]; int dp[200005]; int n; int next_() { int k=0; int sum=1; int len=strlen(s); p[0]=0; dp[0]=1; for(int i=1;i<len;i++) { while(k>0&&s[k]!=s[i]) k=p[k-1]; if(s[k]==s[i]) k++; if(k>0) dp[i]=(dp[k-1]+1)%10007; else dp[i]=1; sum=(sum+dp[i])%10007; p[i]=k; } return sum; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%s",&n,s); printf("%d ",next_()); } return 0; }