hdu 6153 A Secret kmp

题意:

给定两个字符串 求一个串每个后缀在另一个串中出现的次数

思路:

把两个串都倒过来 给模式串做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 */
原文地址:https://www.cnblogs.com/general10/p/7398845.html