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
    */
  • 相关阅读:
    [刷题] IDA*
    [BZOJ1330] Editing a Book
    [BZOJ5449] 序列
    [刷题] 搜索剪枝技巧
    [XJOI3529] 左右
    [CF920E] Connected Components?
    [第18届 科大讯飞杯 J] 能到达吗
    洛谷 P4779 【模板】单源最短路径(标准版)
    洛谷 P1175 表达式的转换
    pipioj 1291 中缀表达式转后缀表达式I
  • 原文地址:https://www.cnblogs.com/Just--Do--It/p/6491678.html
Copyright © 2011-2022 走看看