码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces - 432D Prefixes and Suffixes

时间:2020-02-21 16:23:11      阅读:50      评论:0      收藏:0      [点我收藏+]

标签:oid   inline   +=   记录   getc   prefix   char   状态   void   

这道题竟然不是\(spj\)?(我的英语好菜啊

很容易想到用\(kmp\)

第一个答案就是从\(n\)开始往前找\(nxt\),显然这可以保证匹配。

第二个答案其实也很简单:我们用\(nxt\)来做一个\(dp\)。因为我们最后输出的是\(dp[len[i]]\)\(len\)是相同前缀后缀的长度),这显然是此长度的最后一个状态,那我们倒着做\(dp\),最后总会被最后一个状态记录。

#include<cstdio>
#include<cstring>

const int N = 1e5 + 2;

char s[N];
int nxt[N], n, p[N], cnt[N], m;

int read() {
    int x = 0, f = 1; char s;
    while((s = getchar()) > '9' || s < '0') {if(s == '-') f = -1;}
    while(s <= '9' && s >= '0') {
        x = (x << 1) + (x << 3) + (s ^ 48);
        s = getchar();
    }
    return x * f;
}

void getNxt() {
    int j = 0;
    for(int i = 2; i <= n; ++ i) {
        while(j && s[i] != s[j + 1]) j = nxt[j];
        if(s[i] == s[j + 1]) ++ j;
        nxt[i] = j;
    }
}

int main() {
    scanf("%s", s + 1); n = strlen(s + 1);
    getNxt();
    int pos = n;
    while(pos) {
        p[++ m] = pos;
        pos = nxt[pos];
    }
    for(int i = 1; i <= n; ++ i) cnt[i] = 1;
    for(int i = n; i >= 1; -- i) cnt[nxt[i]] += cnt[i];
    printf("%d\n", m);
    for(int i = m; i >= 1; -- i) printf("%d %d\n", p[i], cnt[p[i]]);
    return 0;
}

CodeForces - 432D Prefixes and Suffixes

标签:oid   inline   +=   记录   getc   prefix   char   状态   void   

原文地址:https://www.cnblogs.com/AWhiteWall/p/12341693.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!