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

432D Prefixes and Suffixes

时间:2019-09-01 10:22:32      阅读:47      评论:0      收藏:0      [点我收藏+]

标签:需要   出现   color   ==   inline   include   std   clu   后缀   

题目大意

给你一个串

对于一个子串如果它既是前缀又是后缀

输出它的长度以及它在原串中一共出现了多少次

分析

对于既是前缀又是后缀的判断和126B相同

然后我们只需要记录每个不同的z[i]出现了多少次

然后对于每个合法z[i]输出所有大于z[i]的数的出现次数即可

因为如果长度为z[i]的前缀是最长前缀

那么小于z[i]的前缀一定合法

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
char s[100100];
int n,z[100100],sum[100100],cnt,ans[100100];
inline void get_z(){
    int i,j,k,l=0,r=0;
    for(i=1;i<n;i++){
      if(i<=r)z[i]=min(r-i+1,z[i-l]);
      while(i+z[i]<n&&s[z[i]]==s[z[i]+i])z[i]++;
      if(i+z[i]-1>r)r=i+z[i]-1,l=i; 
    }
}
int main(){
    int i,j,k;
    scanf("%s",s);
    n=strlen(s);
    get_z();
    for(i=1;i<n;i++){
      sum[z[i]]++;
      if(z[i]==n-i)ans[++cnt]=z[i];
    }
    printf("%d\n",cnt+1);
    sort(ans+1,ans+cnt+1);
    for(i=n-1;i>0;i--)sum[i]+=sum[i+1];
    for(i=1;i<=cnt;i++)printf("%d %d\n",ans[i],sum[ans[i]]+1);
    printf("%d %d\n",n,1);
    return 0;
}

432D Prefixes and Suffixes

标签:需要   出现   color   ==   inline   include   std   clu   后缀   

原文地址:https://www.cnblogs.com/yzxverygood/p/11441376.html

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