CF432D Prefixes and Suffixes

CF432D Prefixes and Suffixes

The meaning of problems

Gives you a long string of length n, "perfect substring" appears both its prefix is ​​also its suffix, the number seeking "perfect substring" and statistical sub-strings in a long string of number

analysis

Nex find an array, the number of times each prefix appears obtained from nex [n] go down the line

In fact, this question Shi, KMP seek each prefix number of questions arise template

Prefix number appears written request

    for(int i = 1 ; i <= n ; ++i) num[i]++;
    for(int i = n ; i >= 1 ; --i) num[nex[i]] += num[i];

This means, first of all i prefix length has its own large, that is, 1

In consideration of the long prefixed i can put it in the number of transitions to whom? Prefix itself has calculated, the calculation is not as long as the next prefix itself, NEX [i] is his longest common prefix and suffix, i.e. at a right end point i, NEX length [i] and prefix substring the same, so i appeared many times, nex [i] should also add prefix number he appeared

    for(int i = 1 ; i <= n ; ++i) num[nex[i]]++;
    for(int i = n ; i >= 1 ; --i) num[nex[i]] += num[i];
    for(int i = 1 ; i <= n ; ++i) num[i]++;

This means, first excluded his own, and then add the final;

The first good understanding of personal recommendation, shorter

On this question the code

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1e5+100;
int n;
int nex[N] , num[N] , cnt[N];
char c[N];
int main()
{
    scanf("%s",c+1); n = strlen(c+1);
    for(int i = 2 , k = 0 ; i <= n ; ++i)
    {
        while(k && c[i] != c[k + 1]) k = nex[k];
        if(c[i] == c[k + 1]) k++; nex[i] = k;
    }
    int tot = 0 , k = nex[n];
    while(k) cnt[++tot] = k , k = nex[k];
    printf("%d\n" , tot + 1);
//  for(int i = 1 ; i <= n ; ++i) num[i]++;
//  for(int i = n ; i >= 1 ; --i) num[nex[i]] += num[i];
    
    for(int i = 1 ; i <= n ; ++i) num[nex[i]]++;
    for(int i = n ; i >= 1 ; --i) num[nex[i]] += num[i];
    for(int i = 1 ; i <= n ; ++i) num[i]++;
    for(int i = tot ; i >= 1 ; --i)
        printf("%d %d\n" , cnt[i] , num[cnt[i]]);
    printf("%d 1\n" , n);
    return 0;
}

Guess you like

Origin www.cnblogs.com/R-Q-R-Q/p/12141659.html