zoukankan      html  css  js  c++  java
  • HDU 3336 Count the String(KMP+DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=3336

    题意:给出一个字符串,计算所有前缀在字符串中出现的次数。

    思路:考虑KMP的next[]来解题。next[i]=j表示最大的j使得0~j==i-j~i。

            对于样例的next[]分析如下:

                      0   1   2   3

          a[]        a    b   a   b

          next[]   -1   0   0   1

         dp[i]表示子串a[0~i]共含有以a[i]为结尾的前缀的数目,则以a[i]结尾的前缀数就是自己本身加上以a[next[i]]结尾的前缀数,即dp[next[i]]。

         

     1 #include<iostream> 
     2 #include<cstring>
     3 using namespace std;
     4 
     5 const int maxn = 200000 + 5;
     6 
     7 int n;
     8 
     9 char a[maxn];
    10 int next[maxn];
    11 int dp[maxn];
    12 
    13 void get_next()
    14 {
    15     int i = -1, j = 0;
    16     ::next[0] = -1;
    17     int l = strlen(a);
    18     while (j < l)
    19     {
    20         if (i == -1 || a[i] == a[j])
    21             ::next[++j] = ++i;
    22         else
    23             i = ::next[i];
    24     }
    25 }
    26 
    27 int main()
    28 {
    29     //freopen("D:\txt.txt", "r", stdin);
    30     int t;
    31     cin >> t;
    32     while (t--)
    33     {
    34         cin >> n;
    35         cin >> a;
    36         get_next();
    37         memset(dp, 1, sizeof(dp));
    38         dp[0] = 0;
    39         int sum = 0;
    40         for (int i = 1; i <= n; i++)
    41         {
    42             dp[i] = dp[::next[i]] + 1;
    43             sum += dp[i] % 10007;
    44         }
    45         cout << sum % 10007 << endl;
    46     }
    47     return 0;
    48 }
  • 相关阅读:
    洛谷7月月赛 B 题解
    undone
    树剖学习
    关于两周后noip---小计划
    线段树技巧练习--GSS1
    链式前向星存图及注意要点
    错题集合
    树上差分问题
    2020暑假学习内容整理及后续计划
    安利大佬博客
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6357966.html
Copyright © 2011-2022 走看看