Codeforces 432D-Prefixes and Suffixes

Posted qjy73

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 432D-Prefixes and Suffixes相关的知识,希望对你有一定的参考价值。

传送门:Codeforces 432D-Prefixes and Suffixes

题意

给定一个字符串,找出其所有相同的前缀和后缀,每行打印两个数字a,b,表示前缀(后缀)的长度,以及它在字符串中出现的次数。

题解

前置知识:统计每个前缀在原字符串中出现的次数。
考虑位置(i)的前缀函数值(nxt[i])。根据定义,其意味着字符串(s)一个长度为(nxt[i])的前缀在位置(i)出现并以(i) 为右端点,同时不存在一个更长的前缀满足前述定义。与此同时,更短的前缀可能以该位置为右端点。容易看出,我们遇到了在计算前缀函数时已经回答过的问题:给定一个长度为(j)的前缀,同时其也是一个右端点位于(i)的后缀,下一个更小的前缀长度(k< j)是多少?该长度的前缀需同时也是一个右端点为(i)的后缀。因此以位置(i)为右端点,有长度为(nxt[i])的前缀,有长度为(nxt[nxt[i]-1])的前缀,有长度为(nxt[nxt[nxt[i]-1]-1])的前缀,等等,直到长度变为0。故而我们可以通过下述方式计算答案。

vector<int> ans(n + 1);
for (int i = 0; i < n; i++) ans[nxt[i]]++;
for (int i = n - 1; i > 0; i--) ans[nxt[i - 1]] += ans[i];
for (int i = 0; i <= n; i++) ans[i]++;

(参见OI-wiki

预处理出每个前缀出现的次数,字符串所有相等的前缀和后缀可以通过不断地nxt获得。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;

const int N=1e5+10; 
char a[N];

int nxt[N],cnt[N];
struct node{
    int pos,num;
}ans[N];
int tot;
int la;

void getnxt(char *p){
    nxt[0]=0;
    for(int i=1;i<la;i++){
        int j=nxt[i-1];
        while(j>0&&p[i]!=p[j]) j=nxt[j-1];
        if(p[i]==p[j]) j++;
        nxt[i]=j;
    }
}

void solve(){
    for(int i=0;i<la;i++) cnt[nxt[i]]++;
    for(int i=la-1;i>=0;i--) cnt[nxt[i-1]]+=cnt[i];
    for(int i=0;i<=la;i++) cnt[i]++;
}

bool cmp(node a,node b){
    return a.pos<b.pos;
}

int main(){
    scanf("%s",a);
    la=strlen(a);
    getnxt(a);
    solve();
    int now=la;
    while(now){
        ans[++tot].pos=now;
        ans[tot].num=cnt[now];
        now=nxt[now-1];
    }
    sort(ans+1,ans+1+tot,cmp);
    printf("%d
",tot);
    for(int i=1;i<=tot;i++){
        printf("%d %d
",ans[i].pos,ans[i].num);
    }
    return 0;
}



以上是关于Codeforces 432D-Prefixes and Suffixes的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #432 A

Codeforces 432D Prefixes and Suffixes

Codeforces 432D Prefixes and Suffixes (KMP后缀数组)

CodeForces 432D Prefixes and Suffixes:KMP + dp

Codeforces Round #432 B

Codeforces Round #432 C