zoukankan      html  css  js  c++  java
  • hdu 3336: Count the string(KMP dp)

    题目链接

    题意:求给定字符串中,可以与某一前缀相同的所有子串的数量

    做这道题需要明白KMP算法里next[]数组的意义

    首先用一数组nex[](这里与之前博客中提到的next明显不同)存储前缀后缀最长公共元素长度。(nex[i]表示,在S[1~i](在标号从1开始的情况下)这个字串中,前缀后缀最长公共元素长度

    然后使用一数组dp[],dp[x]中存放 S[1~x]中共含有 以S[x]结尾的&&与某一字串相同 字串的个数

    这样递推一下,然后把所有dp[i]求个和就是ans了

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=2e5+7;
    const int mod=10007;
    char T[N],S[N];
    int nex[N];
    int dp[N]; 
    int slen;
    
    void getNext()
    {
        int j,k;
        j=0;k=-1;nex[0]=-1;
        while(j<slen)
            if(k==-1||S[j]==S[k])
                nex[++j]=++k;
            else
                k=nex[k];
    }
    void printNext()
    {
        for(int i=0;i<slen;i++)
            printf("%3c",S[i]);
        puts("");
        for(int i=1;i<=slen;i++)
            printf("%3d",nex[i]);
        puts("");
        for(int i=1;i<=slen;i++)
            printf("%3d",dp[i]);
        puts("");
    }
    
    int main()
    {
        int t;scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&slen);
            scanf("%s",S);
            getNext();
            int sum=0;
            for(int i=1;i<=slen;i++)
            {
                dp[i]=dp[nex[i]]+1;
                sum=(sum+dp[i])%mod;
            }
    //        printNext();
            printf("%d
    ",sum);
        }
    }
    /*
    55
    6
    111111
    6
    121212
    6
    123123
    */
  • 相关阅读:
    正则表达式的贪婪匹配(.*)和非贪婪匹配(.*?)
    jQuery + css 公告从左往右滚动
    C# process 使用方法
    存储过程与SQL的结合使用
    img标签的方方面面
    kibana 5.0.0-alpha5 安装
    es5.0 v5.0.0-alpha 编译安装
    奇怪的hosts文件
    阿里云 api 的文档拼写错误
    centos 7 systemd docker http proxy
  • 原文地址:https://www.cnblogs.com/Just--Do--It/p/6491678.html
Copyright © 2011-2022 走看看