HDU 6153 A Secret
题目:http://acm.hdu.edu.cn/showproblem.php?pid=6153
题意:给定两个串,求其中一个串 s
的每个后缀在另一个串 t
中出现的次数。
题解:把两个串都 reverse 一下,给 t
做个 KMP 之后让 s
在 KMP 出来的结果上跑一遍就好了。
kmp模板题。
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> #include<set> #define lson i<<1 #define rson i<<1|1 using namespace std; const int N=1e6+5; const int mod=1e9+7; char s[N],t[N]; int f[N],cnt[N]; int n,m; void getnext() { f[0]=f[1]=0; for(int i=1;i<m;i++) { int j=f[i]; while(j&&s[i]!=s[j]) j=f[j]; f[i+1]=(s[i]==s[j])?j+1:0; } } void kmp() { memset(cnt,0,sizeof(cnt)); for(int i=0,j=0;i<n;i++) { while(j&&t[i]!=s[j]) j=f[j]; j+=(t[i]==s[j]); cnt[j]++; } for(int i=m;i>0;i--) cnt[f[i]]+=cnt[i]; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%s%s",t,s); n=strlen(t); m=strlen(s); reverse(t,t+n); reverse(s,s+m); getnext(); kmp(); int ans=0; for(int i=1;i<=m;i++) ans=(ans+1LL*i*cnt[i]%mod)%mod; printf("%d\n",ans); } return 0; }