Codeforce432D Prefixes and Suffixes

题意:输入一个字符串,问前缀和后缀相同的字符串长度以及这些字符串出现的次数

题解:

方法1:首先计算前缀和后缀相等的字符串,可以发现这就是KMP中next数组的定义while(next[t]) t = ne[t]可以找到所有满足条件的串

这时候只要算每个字符串出现的次数,设dp[i]为前缀在串中出现的次数,那么dp[next[i]] += dp[i]这里很好理解,每一个i都会对next[i]作出贡献,倒着dp,初始化为1

方法2:这道题也可以用后缀数组来做,后缀数组计算出height数组,那么只要计算所有后缀和整个串的最长公共前缀,等于后缀长度的就是满足条件的串

最后计算串出现的次数,可以在计算最长公共前缀的时候记录在数组,最后算一个后缀和就可以

这里用方法1

#include <bits/stdc++.h>
#define maxn 101000
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
char s[maxn];
int ne[maxn], dp[maxn];
vector<pair<int ,int > >v;
void kmp_init(char *x,int l,int *next){
    int i = 0, j = next[0] = -1;
    while(i<l){
        while(j!=-1&&x[i]!=x[j]) j = next[j];
        next[++i] = ++j;
    }
}
int main(){
    scanf("%s", s);
    int l = strlen(s);
    kmp_init(s, l, ne);
    for(int i=l;i>=1;i--){
        dp[i]++;
        dp[ne[i]] += dp[i];
    }
    for(int i=1;i<=l;i++) cout<<ne[i]<<" ";cout<<endl;
    int t = l;
    while(t){
        v.push_back(make_pair(t, dp[t]));
        t = ne[t];
    }
    sort(v.begin(), v.end());
    cout<<v.size()<<endl;
    for(auto j:v) cout<<j.first<<" "<<j.second<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/Noevon/p/8331106.html