HDU - 3336 (Next數組+dp)

Count the string   HDU - 3336    

題意:給定字符串s,求s的所有前綴作爲子串在s中出現的次數和。

思路:考慮dp

dp[i] 表示以第i個字母結尾的所有後綴與s的前綴的匹配次數。

按照最暴力的想法來做的話,肯定我得枚舉以第i個字母結尾的每個後綴。

其實也可以這樣想:dp[i] 等於s(0,i)最長後綴對結果的貢獻加1。然後又kmp裏Next數組可以得知,s(0,i)的最長後綴等於Next[i]對應的s的前綴。

由此可得:dp[i] = dp[Next[i]]+1;  dp[0] = 0;

吐槽:此題數據太水。。。

#include <bits/stdc++.h>
using namespace std;
const int mod = 10007;
char s[2000005];
int dp[2000005],Next[2000005];
void getNext(char s[])
{
    int len = strlen(s),i = 0;
    int k = -1;
    Next[0] = -1;
    while(i < len)
    {
        if(k == -1 || s[i] == s[k])
        {
            Next[++i] = ++k;
        }
        else k = Next[k];
    }
}
int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        scanf("%d",&n);
        scanf("%s",s);
        getNext(s);
        dp[0] = 0;
        int ans = 0;
        for(int i = 1; i <= n; i++)
        {
            dp[i] = dp[Next[i]]+1;
            dp[i] %= mod;
            ans += dp[i];
            ans %= mod;
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章