Count the string HDU

题意:

  求一个字符串的每个前缀在这个字符串中出现次数的加和

解析:

  默默的骂一句。。。傻xkmp。。博主心里气愤。。。

  拓展kmp就好多了。。。

因为拓展kmp每匹配一次   就相当于这些前缀出现了一次

如abcabc

abcabc  与 abcabc匹配 为6  这个6就相当于 abcabc  abcab  abca abc ab a各出现了一次

abcabc  与 bcabc 匹配 0

····

abcabc 与 abc 匹配 为3 相当于abc ab  a 各出现了一次

明白了吧。。

kmp还用dp  原谅我没看懂  dp蒟蒻。。。

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <ctime>
using namespace std;
typedef long long ll;
typedef pair<ll, int> P;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-10;
const int maxn = 2e5+7;
const int mod = 1e9+7;
 
int T;
int n;
char s[maxn];
int dp[maxn];
 
void solve()
{
    int ans = 0;
    memset(dp,0,sizeof(dp));
    int pos = 1,i = 0;
    while(i+1<n&&s[i]==s[i+1]) i++;
    dp[1] = i;
    dp[0] = n;
    for(int i = 2;i < n;i++){
        if(dp[i-pos]+i<dp[pos]+pos){
            dp[i] = dp[i-pos];
        }
        else{
            int j = dp[pos]+pos-i;
            if(j<0) j = 0;
            while(i+j<n&&s[j]==s[i+j]){j++;}
            dp[i] = j;
            pos = i;
        }
    }
    for(int i = 0;i < n;i++){
        ans+=dp[i];
    }
    cout<<ans%10007<<endl;
}
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        scanf("%s",s);
        solve();
    }
    return 0;
}
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
原文地址:https://www.cnblogs.com/WTSRUVF/p/9477468.html