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

Codeforces 432D-Prefixes and Suffixes

时间:2020-03-14 16:58:58      阅读:48      评论:0      收藏:0      [点我收藏+]

标签:str   span   tps   code   pre   force   printf   test   前缀   

传送门: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\n",tot);
    for(int i=1;i<=tot;i++){
        printf("%d %d\n",ans[i].pos,ans[i].num);
    }
    return 0;
}



Codeforces 432D-Prefixes and Suffixes

标签:str   span   tps   code   pre   force   printf   test   前缀   

原文地址:https://www.cnblogs.com/qjy73/p/12492525.html

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