• hdu6153 扩展kmp求一个字符串的后缀在另一个字符串出现的次数。


    /**
    题目:hdu6153
    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6153
    题意:给定两个串,求其中一个串t的每个后缀在另一个串s中出现的次数乘以其长度之和。
    思路:扩展kmp
    先将两个字符串翻转过来。那么变成求t串每个前缀在s串出现的次数。
    直接扩展kmp求出extend[i]表示s串[i,n-1]子串和t串的最长公共前缀。
    那么s串从i开始和t串前缀有匹配的贡献为1+2+...+extend[i] = extend[i]*(extend[i]+1)/2;
    
    */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <iostream>
    #include <cmath>
    #include <vector>
    #include <map>
    using namespace std;
    typedef long long LL;
    #define ms(x,y) memset(x,y,sizeof x)
    typedef pair<int, int> P;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    const int maxn = 1e6+100;
    char s[maxn], t[maxn];
    int Next[maxn], extend[maxn];
    int cnt[maxn];
    LL ans;
    void GetNext(char *T,int* next)
    {
        int a=0;
        int Tlen=strlen(T);
        next[0]=Tlen;
        while(a<Tlen-1&&T[a]==T[a+1]) a++;
        next[1]=a;
        a=1;
        for(int k=2;k<Tlen;k++)
        {
            int p=a+next[a]-1,L=next[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++;
                next[k]=j;
                a=k;
            }
            else next[k]=L;
        }
    }
    
    void GetExtend(char *S,char *T,int* next,int* extend)
    {
        int a=0;
        GetNext(T,next);
        int Slen=strlen(S);
        int Tlen=strlen(T);
        int MinLen=Slen<Tlen? Slen:Tlen;
        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=next[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;
        }
    }
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            scanf("%s%s",s,t);
            ms(cnt,0);
            int n = strlen(s);
            int m = strlen(t);
            reverse(s,s+n);
            reverse(t,t+m);
            GetExtend(s,t,Next,extend);
            ans = 0;
            for(int i = 0; i < n; i++){
                ans = (ans+(LL)extend[i]*(extend[i]+1)/2)%mod;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    一文掌握Docker Compose
    Flannel配置详解
    Helm二:安装
    Helm一:简介
    ubuntu内核及系统升级
    Ogre 编辑器一(MyGUI+Ogre整合与主界面)
    MyGUI 解析
    Ogre 监听类与渲染流程
    OpenGL 阴影之Shadow Mapping和Shadow Volumes
    Ogre RTSS组件解析
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/7403509.html
Copyright © 2020-2023  润新知