zoukankan      html  css  js  c++  java
  • Codeforces 432 D. Prefixes and Suffixes


    用扩展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 = s1s2...s|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 + 1...sj.
    • 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 s1s2...s|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
    ",na);
        for(int i=0;i<na;i++)
        {
            printf("%d %d
    ",ans[i].a,ans[i].b);
        }
        return 0;
    }
    




  • 相关阅读:
    【NXOpen.UF扩展】修改表达式
    NX二次开发 克隆
    C++手动加载CLR运行托管程序(CLR Hosting)
    C++/CLR 使用(VS2012,VS2013,VS2015)编写
    解决VS2015安装后stdio.h ucrtd.lib等文件无法识别问题,即include+lib环境变量配置
    NX 图标
    【错误分析】NX error status: 32
    NX CAM 读取加工参数
    CAM 模板样式表
    锁定NX原生界面 & 锁定界面更新
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/3984715.html
Copyright © 2011-2022 走看看