zoukankan      html  css  js  c++  java
  • Count the string---hdu3336(kmp Next数组的运用)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3336

    题意就是求串s的前缀的个数和;

    例如:abab

    前缀 个数

    a     2

    ab    2

    aba   1

    abab  1

    总数:6

    dp[i] 表示前面的字符以s[i-1]结尾的前缀个数;上列中dp[4]=2(以最后一个字符b结尾的前缀) {abab,ab};

    可以看出增加一个字母会产生一个新的前缀,那就是整个串,之前的前缀就是Next[i]的位置所对应的dp,即dp[Next[i]];

    所以dp[i] = dp[Next[i]] + 1;-_-主要是仔细的想一下,有点绕;

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    const int N = 2e6+7;
    const int mod = 10007;
    
    char s[N];
    int dp[N], n, Next[N];
    
    void GetNext()
    {
        int i=0,j=-1;
        Next[0] = -1;
        while(i<n)
        {
            if(j==-1 || s[i]==s[j])
                Next[++i] = ++j;
            else
                j = Next[j];
        }
    }
    int main()
    {
        int T, sum;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d", &n);
            scanf("%s", s);
            GetNext();
            memset(dp, 0, sizeof(dp));
            sum = 0;
            for(int i=1; i<=n; i++)
            {
                dp[i] = dp[Next[i]] + 1;
                sum = (sum + dp[i]) % mod;
            }
            printf("%d
    ", sum);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    分解质因数
    大素数测试和分解质因数
    快速幂
    欧拉函数
    素数
    gcd,lcm,ext_gcd,inv
    凸包问题 poj 2187
    map的 简单用法
    判断线段是否在园内
    2-sat 问题
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/4839386.html
Copyright © 2011-2022 走看看