HDU6153-A Secret ex-kmp

来源:互联网 发布:为什么淘宝开店开不了 编辑:程序博客网 时间:2024/05/16 08:18

转载自http://blog.csdn.net/qq_36345036/article/details/77414795

Sample Input

2
aaaaa
aa
abababab
aba

Sample Output

13
19
Hint

case 2:
Suffix(S2,1) = “aba”,
Suffix(S2,2) = “ba”,
Suffix(S2,3) = “a”.
N1 = 3,
N2 = 3,
N3 = 4.
L1 = 3,
L2 = 2,
L3 = 1.
ans = (3*3+3*2+4*1)%1000000007.

题目大意:给出两个字符串S1,S2,求S2的所有后缀在S1中出现的次数与其长度的乘积之和。

原来是ex-kmp的模板题。。。

#include <iostream>#include <string>#include <string.h>#include <cstring>#include <algorithm>using namespace std;const int maxn = 1e6 + 10;const int mod = 1e9 + 7;typedef long long ll;int cnt[maxn];/*扩展KMPNext[i]: P[i..m-1] 与 P[0..m-1]的最长公共前缀ex[i]: T[i..n-1] 与 P[0..m-1]的最长公共前缀*/inline ll Add(ll n){    ll m=((n%mod)*((n+1)%mod)/2)%mod;    return m;}char T[maxn],P[maxn];int Next[maxn],ex[maxn];void pre_exkmp(char P[]){    int m=strlen(P);    Next[0]=m;    int j=0,k=1;    while(j+1<m&&P[j]==P[j+1]) j++;    Next[1]=j;    for(int i=2; i<m; i++)    {        int p=Next[k]+k-1;        int L=Next[i-k];        if(i+L<p+1) Next[i]=L;        else        {            j=max(0,p-i+1);            while(i+j<m&&P[i+j]==P[j]) j++;            Next[i]=j;            k=i;        }    }}void exkmp(char P[],char T[]){    int m=strlen(P),n=strlen(T);    pre_exkmp(P);    int j=0,k=0;    while(j<n&&j<m&&P[j]==T[j]) j++;    ex[0]=j;    for(int i=1; i<n; i++)    {        int p=ex[k]+k-1;        int L=Next[i-k];        if(i+L<p+1) ex[i]=L;        else        {            j=max(0,p-i+1);            while(i+j<n&&j<m&&T[i+j]==P[j]) j++;            ex[i]=j;            k=i;        }    }}int main(){    ios::sync_with_stdio(false);    int t;    cin >> t;    while(t --)    {        cin >> T >> P;        int lenT = strlen(T);        int lenP = strlen(P);        reverse(T, T + lenT);        reverse(P, P + lenP);        pre_exkmp(P);        memset(Next, 0,sizeof(Next));        memset(ex, 0, sizeof(ex));        exkmp(P, T);        ll ans = 0;        for(int i = 0; i < lenT; ++ i)        {            if(ex[i])                ans = (ans + Add(ex[i]) % mod) % mod;        }        cout << ans % mod << endl;    }    return 0;}