2017CCPC网赛1004(HDU 6153)

来源:互联网 发布:ipad刻字热门句子知乎 编辑:程序博客网 时间:2024/06/02 02:32

题意:给你两个字符串  求第二个字符串的后缀在第一个字符串中出现的次数;

题解:比赛的时候全懵逼,各种奇葩思路,后缀数组优化KMP什么的,最后结束比赛才在学长的指导下,知道了用KMP的性质和后缀数组的特性去解题,直接A掉

#include<iostream>#include<algorithm>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<cstring>#define N 1000005#define mod 1000000007using namespace std;char a[N];char b[N];char c[N];int Next[N]; int first[N];int aa[N];void intex(char a[],int Next[],int e){int i=0;int j=-1;Next[0]=-1;while(i<e){if(j==-1||a[i]==a[j])  Next[++i]=++j;else j=Next[j];}return ;}void kmp(char a[],char c[],int Next[],int e,int w){int i=0;int j=0;while(i<e){if(j==-1||a[i]==c[j]){if(j!=-1)  first[j]++;i++;j++;if(j==w)  j=Next[j];}else{   j=Next[j];}} return ;}int main(){int T;scanf("%d",&T);getchar();while(T--){   memset(a,0,sizeof(a));   memset(b,0,sizeof(b));   memset(c,0,sizeof(c));   scanf("%s %s",a,b);   int len=strlen(b);   for(int i=0;i<len;i++)  c[i]=b[len-i-1];   memset(b,0,sizeof(b));   memset(first,0,sizeof(first));   intex(c,Next,len);   int len1=strlen(a);   for(int i=0;i<len1;i++)  b[i]=a[len1-i-1];   kmp(b,c,Next,len1,len);   for(int i=len;i>0;i--){     first[Next[i]-1]+=first[i-1];   }   long long ans=0;       for(int i=0;i<len;i++)       ans=(ans+1ll*first[i]*(i+1)%mod)%mod;       printf("%lld\n",ans);}return 0;}