A Secret(KMP)
A Secret
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Others)
Total Submission(s): 830 Accepted Submission(s): 323
Problem Description
Today is the birthday of SF,so VS gives two strings S1,S2 to SF as a present,which have a big secret.SF is interested in this secret and ask VS how to get it.There are the things that VS tell:
Suffix(S2,i) = S2[i...len].Ni is the times that Suffix(S2,i) occurs in S1 and Li is the length of Suffix(S2,i).Then the secret is the sum of the product of Ni and Li.
Now SF wants you to help him find the secret.The answer may be very large, so the answer should mod 1000000007.
Input
Input contains multiple cases.
The first line contains an integer T,the number of cases.Then following T cases.
Each test case contains two lines.The first line contains a string S1.The second line contains a string S2.
1<=T<=10.1<=|S1|,|S2|<=1e6.S1 and S2 only consist of lowercase ,uppercase letter.
Output
For each test case,output a single line containing a integer,the answer of test case.
The answer may be very large, so the answer should mod 1e9+7.
Sample Input
Sample Output
Source
//题意,一个S串,一个T串,问T的每一个后缀串在S串的匹配次数乘后缀串长度之和为多少。
//题解:S,T串逆序后,跑一遍kmp,并且统计匹配度的次数,然后,从lent向前推,因为在匹配时,没有累计T串中T串自己的可匹配情况,
例如逆序后, S: aba T: aba
kmp后,num : 1 1 1 (长为1的匹配数,长为2的匹配数,长为3的匹配数)
而实际,num: 2 1 1 ,因为 aba 匹配成功后,还包含了一次 a 的匹配
所以,最后还要逆序跑一下,利用fail(next)数组来加上,即为答案
1 # include <cstdio> 2 # include <cstring> 3 # include <cstdlib> 4 # include <iostream> 5 # include <vector> 6 # include <queue> 7 # include <stack> 8 # include <map> 9 # include <bitset> 10 # include <sstream> 11 # include <set> 12 # include <cmath> 13 # include <algorithm> 14 # pragma comment(linker,"/STACK:102400000,102400000") 15 using namespace std; 16 # define LL long long 17 # define pr pair 18 # define mkp make_pair 19 # define lowbit(x) ((x)&(-x)) 20 # define PI acos(-1.0) 21 # define INF 0x3f3f3f3f3f3f3f3f 22 # define eps 1e-8 23 # define MOD 1000000007 24 25 inline int scan() { 26 int x=0,f=1; char ch=getchar(); 27 while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();} 28 while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} 29 return x*f; 30 } 31 inline void Out(int a) { 32 if(a<0) {putchar('-'); a=-a;} 33 if(a>=10) Out(a/10); 34 putchar(a%10+'0'); 35 } 36 #define MX 1000050 37 /**************************/ 38 int lens,lent; 39 char S[MX]; 40 char T[MX]; 41 int num[MX]; 42 int fail[MX]; 43 44 void get_next(char * t) 45 { 46 int i=0,j=-1; 47 fail[0]=-1; 48 while(i<lent) 49 { 50 if (j==-1||T[i]==T[j]) 51 fail[++i]=++j; 52 else 53 j=fail[j]; //回溯 54 } 55 } 56 57 void KMP(char *s,char *t) 58 { 59 memset(num,0,sizeof(num)); 60 get_next(t); 61 int i=0,j=0; 62 while (i<lens) 63 { 64 if (j==-1||S[i]==T[j]) 65 { 66 i++,j++; 67 } 68 else j = fail[j]; 69 70 if (j!=-1) num[j]++; 71 72 if (j==lent) j = fail[j]; 73 } 74 } 75 76 int main() 77 { 78 int cas = scan(); 79 while (cas--) 80 { 81 scanf("%s",S); 82 scanf("%s",T); 83 lens = strlen(S); 84 lent = strlen(T); 85 reverse(S,S+lens); 86 reverse(T,T+lent); 87 KMP(S,T); 88 LL ans = 0; 89 for (int i=lent;i>0;i--) 90 { 91 num[fail[i]]+=num[i]; 92 ans = (ans + ((LL)i*num[i])%MOD)%MOD; 93 } 94 printf("%lld\n",ans); 95 } 96 return 0; 97 }