Codeforces 432 D. Prefixes and Suffixes

Codeforces 432 D. Prefixes and Suffixes

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

随着扩展KMP做一个简单的努力…..

D. Prefixes and Suffixes
time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

You have a string s = s1s2s|s|, where |s| is the length of string s, and si its i-th character.

Let’s introduce several definitions:

  • A substring s[i..j] (1 ≤ i ≤ j ≤ |s|) of string s is string sisi + 1sj.
  • The prefix of string s of length l (1 ≤ l ≤ |s|) is string s[1..l].
  • The suffix of string s of length l (1 ≤ l ≤ |s|) is string s[|s| - l + 1..|s|].

Your task is, for any prefix of string s which matches a suffix of string s, print the number of times it occurs in string s as a substring.

Input

The single line contains a sequence of characters s1s2s|s| (1 ≤ |s| ≤ 105) — string s. The string only consists of uppercase English letters.

Output

In the first line, print integer k (0 ≤ k ≤ |s|) — the number of prefixes that match a suffix of string s. Next print k lines, in each line print two integers li ci. Numbers li ci mean that the prefix of the length li matches the suffix of length li and occurs in string s as a substringci times. Print pairs li ci in the order of increasing li.

Sample test(s)
input
ABACABA

output
3
1 4
3 2
7 1

input
AAA

output
3
1 3
2 2
3 1

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn=100100;

char T[maxn],P[maxn];
int next[maxn],ex[maxn];

void pre_exkmp(char P[])
{
    int m=strlen(P);
    next[0]=m;
    int j=0,k=1;
    while(j+1<m&&P[j]==P[j+1]) j++;
    next[1]=j;
    for(int i=2;i<m;i++)
    {
        int p=next[k]+k-1;
        int L=next[i-k];
        if(i+L<p+1) next[i]=L;
        else
        {
            j=max(0,p-i+1);
            while(i+j<m&&P[i+j]==P[j]) j++;
            next[i]=j; k=i;
        }
    }
}

void exkmp(char P[],char T[])
{
    int m=strlen(P),n=strlen(T);
    pre_exkmp(P);
    int j=0,k=0;
    while(j<n&&j<m&&P[j]==T[j]) j++;
    ex[0]=j;
    for(int i=1;i<n;i++)
    {
        int p=ex[k]+k-1;
        int L=next[i-k];
        if(i+L<p+1) ex[i]=L;
        else
        {
            j=max(0,p-i+1);
            while(i+j<n&&j<m&&T[i+j]==P[j]) j++;
            ex[i]=j; k=i;
        }
    }
}

int pos[maxn],sum[maxn],mx=-1;

struct ANS
{
    int a,b;
}ans[maxn];
int na=0;

bool cmp(ANS x,ANS y)
{
    if(x.a!=y.a)return x.a<y.a;
    return x.b<y.b;
}

int lisan[maxn],nl;

int main()
{
    cin>>P;
    pre_exkmp(P);
    int n=strlen(P);
    for(int i=0;i<n;i++)
    {
        pos[next[i]]++;
        lisan[nl++]=next[i];
        mx=max(mx,next[i]);
    }
    sort(lisan,lisan+nl);
    int t=unique(lisan,lisan+nl)-lisan;
    for(int i=t-1;i>=0;i--)
    {
        sum[lisan[i]]=sum[lisan[i+1]]+pos[lisan[i]];
    }
    for(int i=0;i<n;i++)
    {
        if(next[i]==n-i)
        {
            ans[na++]=(ANS){next[i],sum[next[i]]};
        }
    }
    sort(ans,ans+na,cmp);
    printf("%d\n",na);
    for(int i=0;i<na;i++)
    {
        printf("%d %d\n",ans[i].a,ans[i].b);
    }
    return 0;
}

版权声明:来自: 代码代码猿猿AC路 http://blog.csdn.net/ck_boss

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116863.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SplitContainer控件设置固定比例

    SplitContainer控件设置固定比例SplitContainer控件2个panel如何设置均等大小.(竖直拆分)先随意设置空间高的大小,然后如果想要均等显示,则直接设置SplitterDistance为高的一半,即可!随后任意改变控件大小,都不会改变均等显示比例。同理3:7,4:6…

    2022年7月18日
    11
  • 自旋锁和互斥锁区别在哪_互斥锁的实现

    自旋锁和互斥锁区别在哪_互斥锁的实现POSIXthreads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API。线程同步(ThreadSynchronization)是并行编程中非常重要的通讯手段,其中最典型的应用就是用Pthreads提供的锁机制(lock)来对多个线程之间共享的临界区(CriticalSection)进行保护(另一种常用的同步机制是barrier)。Pthreads提供了多种锁机制:…

    2022年10月22日
    0
  • 计算机cpu后面字母代表什么意思,英特尔CPU型号中最后的字母什么意思?如有不懂欢迎驻足停留…「建议收藏」

    计算机cpu后面字母代表什么意思,英特尔CPU型号中最后的字母什么意思?如有不懂欢迎驻足停留…「建议收藏」今天给大家主要讲讲Intel(英特尔)处理器的小常识。可能说过比较多遍了,但是今天说的比较具体,对大家以后要买CPU得有个参考。在Intel处理器中,有各种型号的U,这些型号中后缀都自带字母,比如K、X、M等等,不过还要区分笔记本和台式,相对来说笔记本电脑带的更多,今天就给大伙好好普及一下,如有遗漏,欢迎你们的替补喔。笔记本电脑:M:一般是双核处理器。M前面一位数字是0,就是标准电压处理器(功耗为…

    2022年6月21日
    39
  • java 取余 负数_Java中有关负数取余的计算[通俗易懂]

    java 取余 负数_Java中有关负数取余的计算[通俗易懂]Java中有关负数取余的计算先看测试代码:publicclassSolution{publicstaticvoidmain(String[]args){System.out.println(“2%3=”+2%3);System.out.println(“2%-3=”+2%-3);System.out.println(“-2%3=”+-2…

    2022年5月22日
    34
  • netty编解码器_netty编程实战

    netty编解码器_netty编程实战目录​1Java序列化的缺点2业界主流的编解码框架2.1Google的Protobuf介绍2.2Facebook的Thrift介绍2.3JBossMarshalling介绍 第6章编解码技术1Java序列化的缺点java序列化通过实现Serializable接口来实现 无法跨语言 序列化后的码流太大  序列化性能太低java序列化的两…

    2022年9月28日
    0
  • iOS安全攻防(三):使用Reveal分析他人app

    iOS安全攻防(三):使用Reveal分析他人app

    2021年12月7日
    32

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号