ccpc 2017 网络赛 1004 A Secret (扩展kmp)【模板】
2017-08-20 17:08
621 查看
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.
InputInput 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.
OutputFor 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
Hint
【题解】
kmp题,,刚开始看成AC自动机了 ,,搞了半天一直哇,,后来换KMP就过了,,这读题真是,,
就是求一个一个序列的前缀出现次数与其长度乘积的和,扩展kmp做法。
【AC代码】
还有简洁一点的:
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.
InputInput 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.
OutputFor 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
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题,,刚开始看成AC自动机了 ,,搞了半天一直哇,,后来换KMP就过了,,这读题真是,,
就是求一个一个序列的前缀出现次数与其长度乘积的和,扩展kmp做法。
【AC代码】
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const int N=1e6+10; const int inf=1e9+7; int next_t ,extend ; char s1 ,s2 ; int m,n; int len1,len2; void get_extend() //扩展KMP数组模板 { int j=0,k=1; next_t[0]=len2; while(j+1<len2 && s2[j]==s2[j+1]) j++; next_t[1]=j; for(int i=2;i<len2;++i) { if(next_t[i-k]+i<next_t[k]+k) next_t[i]=next_t[i-k]; else { j=next_t[k]+k-i; if(j<0) j=0; while(i+j<len2 && s2[j]==s2[i+j]) j++; next_t[i]=j; k=i; } } } void e_kmp() { int j=0,k=0; while(j<len1 && j<len2 && s1[j]==s2[j]) j++; extend[0]=j; for(int i=1;i<len1;++i) { int pos=extend[k]+k-1; int l=next_t[i-k]; if(i+l<pos+1) extend[i]=l; else { j=max(0,pos-i+1); while(i+j<len1 && j<len2 && s1[i+j]==s2[j]) j++; extend[i]=j; k=i; } } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%s%s",s1,s2); len1=strlen(s1); len2=strlen(s2); reverse(s1,s1+len1); reverse(s2,s2+len2); get_extend(); ll ans=0; e_kmp(); for(int i=0;i<len1;++i) { ans=(ans+((ll)extend[i]*(extend[i]+1)/2)%inf)%inf; } printf("%lld\n",ans); } return 0; }
还有简洁一点的:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int inf=1e9+7; const int N=1000005; char s1 ,s2 ; ll sum ; int next_t ; int len1,len2; void get_next()//next数组模板 { int i=0,j=-1; next_t[0]=-1; while(i<len2) { while(j!=-1 && s2[i]!=s2[j]) j=next_t[j]; i++; j++; next_t[i]=j; } } void e_kmp() { int i=0,j=0; memset(sum,0,sizeof(sum)); while(i<len1) { if(j==-1||s1[i] == s2[j]) i++,j++; else j=next_t[j]; sum[j]++; if(j==len2) j=next_t[j]; } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%s%s",s1,s2); len1=strlen(s1); len2=strlen(s2); reverse(s1,s1+len1); reverse(s2,s2+len2); get_next(); e_kmp(); ll ans=0; for(int i=len2;i>0;--i) { sum[next_t[i]]+=sum[i]; ans=(ans+sum[i]*i)%inf; } printf("%lld\n",ans); } return 0; }
相关文章推荐
- 【HDU6153 2017中国大学生程序设计竞赛 - 网络选拔赛 D】【KMP 或 扩展KMP】A Secret 匹配串前缀中含有的模板串前缀长度和
- HDU6153 A Secret(扩展KMP)2017中国大学生程序设计竞赛 - 网络选拔赛-1004
- 2017 CCPC网络赛 hdu6153 KMP
- HDU 6153 A Secret(扩展kmp模板题)
- HDU 6153 - A Secret 2017中国大学生程序设计竞赛 - 网络选拔赛 1004 - A Secret
- HDU-2017中国大学生程序设计竞赛-网络选拔赛-1004-A Secret
- HDU 6153 A Secret CCPC网络赛,KMP拓展应用
- A Secret 2017 CCPC 网络选拔赛 hdu 6153
- 扩展KMP总结(模板题hdu2594)
- 扩展KMP模板
- 扩展KMP模板
- 2017 ccpc网络赛 1001 Vertex Cover(二分图 构造)HDU6150
- hdu 6153 A Secret(kmp||扩展kmp)
- HDU 6153 A Secret【KMP||扩展KMP】
- HDU 6153 A Secret(KMP/扩展KMP)
- hdoj1841Find the Shortest Common Superstring【扩展KMP模板】
- hdu 6153 A Secret(kmp||扩展kmp)
- 2017 ACM-ICPC乌鲁木齐网络赛 G. Query on a string 【KMP+树状数组】
- HDU 2594 - Simpsons’ Hidden Talents(扩展kmp模板)
- [目前未找到题目]扩展KMP模板