HDU6153-A Secret
来源:互联网 发布:淘宝上好的家具店 编辑:程序博客网 时间:2024/06/05 08:13
A Secret
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Others)
Total Submission(s): 254 Accepted Submission(s): 105
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
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.
Source
2017中国大学生程序设计竞赛 - 网络选拔赛
题目大意:给出两个字符串
解题思路:感谢大家的指正~~~
kmp匹配的时候会跳过一些字符,而这些字符可能会与前缀匹配,所以原先的做法会漏掉一些情况,比如下面两个串。
所以为了不重不漏,就要用扩展kmp求出最长公共前缀,
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<vector>#include<algorithm>#include<string>using namespace std;typedef long long LL;const int MAXN=1e6+5;const int MOD=1e9+7;char txt[MAXN],pat[MAXN];int nxt[MAXN],extend[MAXN];LL ans;void getnxt(char *p){ int plen=strlen(p); nxt[0]=plen; int j=0; while(j+1<plen&&p[j]==p[j+1]) j++; nxt[1]=j; int k=1; for(int i=2;i<plen;i++) { int pos=nxt[k]+k-1; int L=nxt[i-k]; if(i+L<pos+1) nxt[i]=L; else { j=max(0,pos-i+1); while(i+j<plen&&p[i+j]==p[j]) j++; nxt[i]=j; k=i; } }}void e_kmp(char *p,char *t){ int j=0; int plen=strlen(p); int tlen=strlen(t); while(j<tlen&&j<plen&&p[j]==t[j]) j++; extend[0]=j; int k=0; for(int i=1;i<tlen;i++) { int pos=extend[k]+k-1; int L=nxt[i-k]; if(i+L<pos+1) extend[i]=L; else { j=max(0,pos-i+1); while(i+j<tlen&&j<plen&&t[i+j]==p[j]) j++; extend[i]=j; k=i; } }}int main(){ int T; scanf("%d",&T); while(T--) { ans=0; scanf("%s%s",txt,pat); int tlen=strlen(txt); reverse(txt,txt+tlen); int plen=strlen(pat); reverse(pat,pat+plen); getnxt(pat); e_kmp(pat,txt);// for(int i=0;i<tlen;i++)// {// cout<<extend[i]<<" ";// }// cout<<endl; for(int i=0;i<tlen;i++) { ans=(ans+((LL)extend[i]*(extend[i]+1)/2)%MOD)%MOD; } printf("%lld\n",ans); } return 0;}
请忽略以下话: 将
这样第一次匹配为
此时
第二次匹配,在加上
值得注意的是,由于此时文本已匹配完毕,但
接着继续此时
因为
故最终结果为
错误的代码:
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;typedef long long LL;const int MAXN=2e6+5;const int MOD=1e9+7;char pat[MAXN],txt[MAXN];int fail[MAXN];LL ans;void getfail(char *p){ int plen=strlen(p); fail[0]=0,fail[1]=0;//递推初值 for(int i=1;i<plen;++i) { int j=fail[i]; while(j&&p[i]!=p[j]) j=fail[j]; if(p[i]==p[j]) fail[i+1]=j+1; else fail[i+1]=0; }}void kmp(char *t,char *p){ int tlen=strlen(t),plen=strlen(p); LL j=0;//当前结点编号 for(int i=0;i<tlen;++i)//文本串当前指针 { //顺着失配边走,直到可以匹配 while(j&&p[j]!=t[i]) { ans=(ans+(j*(j+1)/2)%MOD)%MOD; j=fail[j]; } if(p[j]==t[i]) { ++j; } if(j==plen) { ans=(ans+j*(j+1)/2)%MOD; j=fail[j]; } } while(j>=1) { ans=(ans+(j*(j+1)/2)%MOD)%MOD; j=fail[j]; }}int main(){ int T; scanf("%d",&T); while(T--) { ans=0; scanf("%s%s",txt,pat); int tlen=strlen(txt); reverse(txt,txt+tlen); int plen=strlen(pat); reverse(pat,pat+plen); getfail(pat);// for(int i=0;i<=plen;++i)// printf("%d ",fail[i]);// printf("\n"); kmp(txt,pat); printf("%lld\n",ans); } return 0;}/*2aaaaaaaabababababa1319*/
- HDU6153-A Secret
- [kmp] hdu6153 A Secret
- HDU6153-A Secret
- hdu6153(kmp) A Secret
- HDU6153-A Secret ex-kmp
- HDU6153 A Secret 扩展KMP
- hdu6153(kmp) A Secret
- hdu6153-exkmp&&脑洞-A Secret
- 【HDU6153】A Secret(扩展KMP)
- [扩展kmp] hdu6153 A Secret
- hdu6153 A Secret CCPC1004 扩展KMP
- hdu6153-A Secret (kmp/扩展kmp)
- hdu6153 A Secret (拓展KMP)
- HDU6153 A Secret(扩展KMP)2017中国大学生程序设计竞赛
- A Secret
- creat a secret folder
- overflow - a secret benifit
- A - Secret Number
- leetcode__02
- 字符与字节的关系。
- 将一个ANSI编码格式纯文本文件以UTF-8的形式读到另一个文件中去
- JavaScript 模板方法模式(es6)
- noip2013day2题解
- HDU6153-A Secret
- 关于两个数相乘, 求其为多少进制
- HDU6152 Friend-Graph【模拟】
- Makefile经典教程(掌握这些足够)
- 2018网易内推笔试-等差数列(python)
- gcc的参数 -I和-L 的用法
- Adapter与Activity通过接口回调进行交互
- 「网络流 24 题」航空路线问题
- NYOJ 17 单调递增最长子序列