zoukankan      html  css  js  c++  java
  • 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
    ", ans);
        }
    
        return 0;
    }
  • 相关阅读:
    【MySQL】自增步长调整
    【Python】异常
    【Python】单例模式
    rabbitMQ-server 下载地址
    函数(六)---内置函数
    # python04---函数
    python02---基础数据类型
    0001-代码仓库-git 命令
    0001-代码仓库-mvn
    腾讯短信接口使用
  • 原文地址:https://www.cnblogs.com/sbfhy/p/7413223.html
Copyright © 2011-2022 走看看