• ZOJ 3587 扩展KMP


    思路:这题确实大帝做得非常机智!字符串先求最长前缀,反的字符串再求一次最长前缀。然后就能够搞了。

    每一个子串出现的次数就是最长前缀的次数嘛!

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<set>
    #include<cmath>
    #include<bitset>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson i<<1,l,mid
    #define rson i<<1|1,mid+1,r
    #define llson j<<1,l,mid
    #define rrson j<<1|1,mid+1,r
    #define INF 0x7fffffff
    #define maxn 100005
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
    void EKMP(char *s,char *t,ll *next,ll *extend)//s[]为主串,t[]为模版串
    {
        int i,j,p,l;
        int len=strlen(t);
        int len1=strlen(s);
        memset(next,0,sizeof(next));
        memset(extend,0,sizeof(extend));
        next[0]=len;
        j=0;
        while(1+j<len&&t[j]==t[1+j])j++;
        next[1]=j;
        int a=1;
        for(i=2; i<len; i++)
        {
            p=next[a]+a-1;
            l=next[i-a];
            if(i+l<p+1)next[i]=l;
            else
            {
                j=max(0,p-i+1);
                while(i+j<len&&t[i+j]==t[0+j])j++;
                next[i]=j;
                a=i;
            }
        }
        j=0;
        while(j<len1&&j<len&&s[j]==t[j])j++;
        extend[0]=j;
        a=0;
        for(i=1; i<len1; i++)
        {
            p=extend[a]+a-1;
            l=next[i-a];
            if(l+i<p+1)extend[i]=next[i-a];
            else
            {
                j=max(0,p-i+1);
                while(i+j<len1&&j<len&&s[i+j]==t[j])j++;
                extend[i]=j;
                a=i;
            }
        }
    }
    char S[maxn],T[maxn];
    ll next[maxn],extend[maxn],sum[maxn],sum1[maxn];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            mem(sum,0);mem(sum1,0);
            scanf("%s%s",S,T);
            EKMP(S,T,next,extend);
            int len1=strlen(S),len2=strlen(T);
            for(int i=0;i<len1;i++)
                sum[extend[i]]++;
            for(int i=len2-1;i>=1;i--)
                sum[i]+=sum[i+1];
            reverse(S,S+len1);
            reverse(T,T+len2);
            EKMP(S,T,next,extend);
            for(int i=0;i<len1;i++)
                sum1[extend[i]]++;
            for(int i=len2-1;i>=1;i--)
                sum1[i]+=sum1[i+1];
            ll ans=0;
            for(int i=1;i<len2;i++)
                ans+=sum[i]*sum1[len2-i];
            printf("%lld
    ",ans);
        }
        return 0;
    }
    /*
    2
    aaabbb
    ab
    ababaabaaaab
    abaab
    */
    



  • 相关阅读:
    2018——测试与信仰
    面试必备----测试用例笔试题分享
    软件测试人员必备网络知识(一):什么是cookie?
    Postman和Selenium IDE开局自带红蓝BUFF属性,就问你要还是不要
    【Loadrunner】LR参数化:利用mysql数据库里面的数据进行参数化
    因果图法设计测试用例
    场景法设计测试用例
    Linux Centos7下安装Python
    Vmware安装与VMware下Linux系统安装
    Python运算符与表达式
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6710693.html
Copyright © 2020-2023  润新知