hdu6153 扩展KMP

hdu6153    A Secret

题意:两个字符串A 、B,问 B 的所有后缀在 A 中出现了多少次。

tags:把两字符串反一下,然后。。就是板子题了。。

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 1000005, mod = 1e9+7;

int nex[N], extend[N];
void getnext(char *T)   // nex[i] 表示 T[i~Tlen-1] 与 T的最长公共前缀
{
    memset(nex, 0, sizeof(nex));
    int i, Tlen = strlen(T);
    nex[0] = Tlen;
    for(i=0; i<Tlen-1 && T[i]==T[i+1]; ++i) ;
    nex[1] = i;
    int a = 1;
    for(int k=2; k<Tlen; ++k)
    {
        int p = a+nex[a]-1, L = nex[k-a];
        if( (k-1)+L >= p )
        {
            int j = (p-k+1)>0 ? (p-k+1) : 0;
            while(k+j<Tlen && T[k+j]==T[j]) ++j;
            nex[k] = j, a = k;
        }
        else nex[k] = L;
    }
}
void getextend(char *S, char *T)  // extend[i] 表示 S[i~Slen-1]与 T 的最长公共前缀
{
    getnext(T);
    int Slen = strlen(S), Tlen = strlen(T), a = 0;
    int MinLen = Slen>Tlen ? Tlen : Slen;
    while(a<MinLen && S[a]==T[a]) ++a;
    extend[0] = a, a = 0;
    for(int k=1; k<Slen; ++k)
    {
        int p = a+extend[a]-1, L = nex[k-a];
        if( (k-1)+L >= p )
        {
            int j = (p-k+1)>0 ? (p-k+1) : 0;
            while(k+j<Slen && j<Tlen && S[k+j]==T[j]) ++j;
            extend[k] = j, a = k;
        }
        else extend[k] = L;
    }
}

char A[N], B[N];
int main()
{
    int T;  scanf("%d", &T);
    while(T--)
    {
        scanf("%s%s", A, B);
        int len1 = strlen(A), len2 = strlen(B);
        reverse(A, A+len1);  reverse(B, B+len2);
        getextend(A, B);
        ll  ans = 0;
        for(int i=0; i<len1; ++i)
        {
            ans += (1LL*extend[i]*(extend[i]+1)/2)%mod;
            ans %= mod;
        }
        printf("%lld\n", ans);
    }

    return 0;
}
posted @ 2017-08-22 19:22  v9fly  阅读(250)  评论(3编辑  收藏  举报