HDU6153(KMP)

来源:互联网 发布:淘宝的广告语 编辑:程序博客网 时间:2024/06/07 13:53

题解:两个字符串转置后倒着跑一遍KMP,最后求这个前缀在匹配串中有几个相加一下即可,接着就是ans[i]*i的总和相加

#include <map>#include <queue>#include <cmath>#include <cstdio>#include <complex>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;typedef long long int ll;const int N=1e6+10;const int MOD=1e9+7;char a[N],b[N];int f[N];ll ans[N];void get_next(){    int m=strlen(b);    f[0]=f[1]=0;    for(int i=1;i<m;i++){        int j=f[i];        while(j&&b[i]!=b[j]) j=f[j];        f[i+1]=b[i]==b[j]?j+1:0;    }}void kmp_count(){    int n=strlen(a),m=strlen(b);    int j=0;    for(int i=0;i<n;i++){        while(j&&b[j]!=a[i]) j=f[j];        if(b[j]==a[i]) j++;        ans[j]++;        if(j==m){            j=f[j];            if(j>m) j=0;        }    }}int main(){int n;    scanf("%d",&n);    while(n--) {        scanf("%s%s",a,b);        reverse(b,b+strlen(b));        reverse(a,a+strlen(a));        memset(ans,0,sizeof(ans));        get_next();kmp_count();        int m=strlen(b);        for(int i=m;i>=1;i--) ans[f[i]]+=ans[i];        ll sum=0;        for(ll i=1;i<=m;i++){           sum=(sum+i*ans[i])%MOD;        }        printf("%lld\n",sum);    }    return 0;}



原创粉丝点击