• codeforces


    http://codeforces.com/problemset/problem/432/D

    转自:https://blog.csdn.net/tc_to_top/article/details/38793973

    题意

    给出一个字符串,求有多少种长度的前缀和后缀相等,并且这种形式的子串在原字符串中出现的次数。

    分析

    首先得到主串的next数组,next数组的含义是next[j]的值表示str[0...j-1](我的next[0]是-1)这个子串的前后缀匹配的最长长度,如样例1
    index  0  1  2  3  4  5  6  7
    str    A  B  A  C  A  B  A
    next   -1 0  0  1  0  1  2  3
    next[6] = 2即ABACAB这个子串的前后缀最长匹配是2(AB),此时表明存在前缀与后缀匹配长度为2的串。
    由此性质我们可以发现满足条件的子串即是next[next[len。。。]]不断往前递归直到为0,因为长的可能会包含短的,我们可以递归得到re数组(re记录的就是子串出现的次数)re数组的递归式为re[next[i]] += re[i];
    #include <cstdio>
    #include <cstring>
    int const MAX = 1e5 + 5;
    char s[MAX];
    int next[MAX];
    int len, pos, num;
    int l[MAX], cnt[MAX], re[MAX];
     
    void get_next(){
        int i = 0, j = -1;
        next[0] = -1;
        while(s[i] != '') {
            if(j == -1 || s[i] == s[j]){
                i ++;
                j ++;
                next[i] = j;
            }else
                j = next[j];
        }
    }
     
    void solve(){
        for(int i = 0; i <= len; i++)
            re[i] = 1;
        for(int i = len; i >= 1; i --)
            if(next[i] != -1)
                re[next[i]] += re[i];
        int pos = len;
        while(pos){
            cnt[num] = re[pos];//次数
            l[num ++] = pos;//长度
            pos = next[pos];
        }   
    }
     
    int main(){
        scanf("%s", s);
        len = strlen(s);
        get_next();
        solve();
        printf("%d
    ", num);
        for(int i = num - 1; i >= 0; i--)
            printf("%d %d
    ", l[i], cnt[i]);
    }
  • 相关阅读:
    css3 object-fit详解
    Timing path
    IUS
    FIFO深度
    UVM中的class--2
    UVM中的class
    Binding
    Concurrent Assertion
    Immediate assertion
    sdf
  • 原文地址:https://www.cnblogs.com/fht-litost/p/9320965.html
Copyright © 2020-2023  润新知