题意:
给定两个字符串 求一个串每个后缀在另一个串中出现的次数
思路:
把两个串都倒过来 给模式串做kmp在主串上跑一边就行了
1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a)) 3 #define debug(a) cerr<<#a<<"=="<<a<<endl 4 using namespace std; 5 typedef long long ll; 6 typedef pair<int,int> pii; 7 8 const int maxn=1e6+10; 9 const int mod=1e9+7; 10 11 int _next[maxn],val[maxn]; 12 char a[maxn],b[maxn]; 13 14 inline void init() 15 { 16 cl(_next,0),cl(val,0); 17 } 18 19 void kmp_pre(char x[],int _next[],int val[]) 20 { 21 int i,j; 22 _next[0]=-1,_next[1]=0; 23 val[0]=0,val[1]=1; 24 int len=strlen(x); 25 for(i=1; i<len; i++) 26 { 27 _next[i+1]=0; 28 val[i+1]=i+1; 29 j=_next[i]; 30 while(j>=0) 31 { 32 if(x[i]==x[j]) 33 { 34 _next[i+1]=j+1; 35 val[i+1]+=val[j+1]; 36 val[i+1]%=mod; 37 break; 38 } 39 j=_next[j]; 40 } 41 } 42 } 43 44 45 ll KMP_Count(char x[],int _next[],char y[],int val[]) 46 { 47 int len=strlen(y),i,j,k; 48 ll ans=0; 49 i=j=k=0; 50 kmp_pre(x,_next,val); 51 for(; i<len; i++) 52 { 53 k=j; 54 j=0; 55 while(k>=0) 56 { 57 if(y[i]==x[k]) 58 { 59 j=k+1; 60 break; 61 } 62 k=_next[k]; 63 } 64 ans+=val[j]; 65 ans%=mod; 66 } 67 return ans; 68 } 69 70 void get() 71 { 72 int lena=strlen(a); 73 int lenb=strlen(b); 74 for(int i=0; i<lena/2; i++) 75 { 76 swap(a[i], a[lena-i-1]); 77 } 78 for(int i=0; i<lenb/2; i++) 79 { 80 swap(b[i], b[lenb-i-1]); 81 } 82 } 83 84 int main() 85 { 86 int T; 87 scanf("%d",&T); 88 while(T--) 89 { 90 init(); 91 scanf("%s",a); 92 scanf("%s",b); 93 get(); 94 printf("%lld ",KMP_Count(b,_next,a,val)); 95 } 96 return 0; 97 }/* 98 99 2 100 aaaaa 101 aa 102 abababab 103 aba 104 105 */