Prefixes and Suffixes

题面

题目描述

给你一个字符串s,对于s的每一个前缀,如果它也是s的一个后缀,输出这个前缀在s中出现了多少次。

输入格式

一个字符串s(长度<=100000);只含有大写字母。

输出格式

第一行输出一个整数k——满足条件的前缀个数;
接下来k行,每行两个整数l,c,代表长度为l的前缀满足条件,在整个字符串中出现了c次。按l从小到大输出。

样例

Input1
ABACABA
Output1
3
1 4
3 2
7 1
Input2
AAA
Output2
3
1 3
2 2
3 1

题解

考虑每一个前缀\(str[0 .. i]\), 假如它也是字符串的后缀的话, 则有\(str[len - i - 1 .. len - 1] = str[0 .. i]\), 即\(match[len - i - 1] = i\).
对于每一个\(i\)判断是否存在\(match[len - i - 1] = i\)即可, 并统计整个\(match[]\)数组中\(match[n] >= i\)的数量即可.

#include <cstdio>
#include <cstring>
#include <algorithm>
 
const int L = (int)1e5;
 
int main()
{
    static char str[L];
    scanf("%s", str);
    int len = strlen(str);
    static int mch[L];
    mch[0] = len - 1, mch[1] = -1;
    for(; mch[1] + 1 < len && str[mch[1] + 1] == str[1 + mch[1] + 1]; ++ mch[1]);
    int p = 1, mx = p + mch[p];
    for(int i = 2; i < len; ++ i)
    {
        mch[i] = std::max(std::min(mx - i, mch[i - p]), -1);
        for(; i + mch[i] < len && str[mch[i] + 1] == str[i + mch[i] + 1]; ++ mch[i]);
        if(i + mch[i] > mx)
            p = i, mx = i + mch[i];
    }
    static int sum[L];
    memset(sum, 0, sizeof(sum));
    for(int i = 0; i < len; ++ i)
        if(~ mch[i])
            ++ sum[mch[i]];
    for(int i = len - 1; i; -- i)
        sum[i - 1] += sum[i];
    int cnt = 0;
    for(int i = 0; i < len; ++ i)
        if(mch[len - i - 1] == i)
            ++ cnt;
    printf("%d\n", cnt);
    for(int i = 0; i < len; ++ i)
        if(mch[len - i - 1] == i)
            printf("%d %d\n", i + 1, sum[i]);
}

转载于:https://www.cnblogs.com/ZeonfaiHo/p/7124636.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值