poj 3693 Maximum repetition substring

The repetition number of a string is defined as the maximum number R such that the string can be partitioned into R same consecutive substrings. For example, the repetition number of "ababab" is 3 and "ababa" is 1.

Given a string containing lowercase letters, you are to find a substring of it with maximum repetition number.

Input

The input consists of multiple test cases. Each test case contains exactly one line, which
gives a non-empty string consisting of lowercase letters. The length of the string will not be greater than 100,000.

The last test case is followed by a line containing a '#'.

Output

For each test case, print a line containing the test case number( beginning with 1) followed by the substring of maximum repetition number. If there are multiple substrings of maximum repetition number, print the lexicographically smallest one.

Sample Input

ccabababc
daabbccaa
#

Sample Output

Case 1: ababab
Case 2: aa

题意:给定一个字符串,求出其子串中,重复次数最多的串,如果有相同的,输出字典序最小的

思路:枚举长度l,把字符串按l分段,这样对于长度为l的字符串,肯定会包含一个分段位置,这样一来就可以在每个分段位置,往后做一次lcp,求出最大匹配长度,然后如果匹配长度有剩余,看剩余多少,就往前多少位置再做一次lcp,如果匹配出来长度更长,匹配次数就加1,这样就可以枚举过程中保存下答案了

这样问题还有字典序的问题,这个完全可以利用sa数组的特性,从字典序最小往大枚举,直到出现一个符合的位置就输出结束

 1 #include<cstring> 
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstdio>
 6 using namespace std;  
 7 int const N=200000+3;  
 8 int wa[N<<1],wb[N<<1],rk[N],h[N],sa[N],num[N],wv[N],lg[N<<1],f[N<<1][17];  
 9 char s[N<<1];  
10 int cmp(int *r,int x,int y,int z){
11     return r[x]==r[y] &&  r[x+z]==r[y+z];  
12 } 
13 void build_sa(char *r,int *sa,int n,int m){
14     int i,j,p,*x=wa,*y=wb;  
15     for(i=0;i<m;i++) num[i]=0;  
16     for(i=0;i<n;i++) num[x[i]=r[i]]++; 
17     for(i=1;i<m;i++) num[i]+=num[i-1];  
18     for(i=n-1;i>=0;i--) sa[--num[x[i]]]=i; 
19     for(p=1,j=1;p<n;j<<=1,m=p){
20         for(p=0,i=n-j;i<n;i++) y[p++]=i;  
21         for(i=0;i<n;i++) if(sa[i]>=j)  y[p++]=sa[i]-j;  
22         for(i=0;i<m;i++) num[i]=0;  
23         for(i=0;i<n;i++) wv[i]=x[y[i]];  
24         for(i=0;i<n;i++) num[wv[i]]++; 
25         for(i=1;i<m;i++) num[i]+=num[i-1];  
26         for(i=n-1;i>=0;i--) sa[--num[wv[i]]]=y[i];  
27         swap(x,y);  
28         for(i=1,p=1,x[sa[0]]=0;i<n;i++)  
29             x[sa[i]]=cmp(y,sa[i],sa[i-1],j)? p-1:p++;  
30     }
31     for(i=0;i<n;i++) rk[i]=x[i];  
32 }   
33 void build_h(char *r,int *sa,int n){
34     int k=0; 
35     for(int i=1;i<=n;i++){
36         if(k) k--;  
37         int j=sa[rk[i]-1];  
38          while ( r[i+k]==r[j+k]) k++;  
39          h[rk[i]]=k; 
40     }
41 }  
42 void build_rmq(int n){
43     for(int i=1;i<=n;i++) f[i][0]=h[i];  
44     for(int j=1;j<=16;j++)  
45         for(int i=1;i<=n;i++) f[i][j]=min(f[i][j-1],f[i+(1<<j-1)][j-1]);       
46 }
47 int query(int x,int y){
48     if(x>y) swap(x,y);  
49     x++;  
50     int k=lg[y-x+1];  
51     return min(f[x][k],f[y-(1<<k)+1][k]);  
52 }
53 int main(){  
54     int cas=0;  
55     for(int i=0;i<=16;i++)   
56         for(int j=(1<<i);j<(1<<i+1);j++)  
57             lg[j]=i;         
58     while (scanf("%s",s)!=EOF){
59         if(strcmp(s,"#")==0) break;  
60         int len=strlen(s);  
61         build_sa(s,sa,len+1,130); 
62         build_h(s,sa,len);  
63         build_rmq(len);  
64       int ans=0,l=0,r=0;  
65       for(int L=1;2*L<=len;L++) 
66           for(int i=0;(i+1)*L<len;i++){
67               int x=L*i,y=L*(i+1);  
68               if(s[x]!=s[y]) continue;  
69               int z=query(rk[x],rk[y]); 
70               int t1=y+z-1;  
71               int t0=0;  
72               for(int j=0;j<L;j++){
73                   if(x-j<0 || s[x-j]!=s[y-j]) break;  
74                   t0=x-j;  
75                   int now=(t1-t0+1)/L;  
76                   if(now>ans || (now==ans && rk[t0]<rk[l]))  
77                       ans=now,l=t0,r=t0+now*L-1;  
78             } 
79           } 
80       printf("Case %d: ",++cas);  
81       if(ans==0) printf("%c\n",s[sa[1]]);  
82       else {
83           for(int i=l;i<=r;i++)  printf("%c",s[i]); 
84           printf("\n");
85       }           
86     }
87     return 0; 
88 }
View Code

 

转载于:https://www.cnblogs.com/ZJXXCN/p/10997980.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的精简博客系统,源码+数据库+毕业论文+视频演示 当下,正处于信息化的时代,许多行业顺应时代的变化,结合使用计算机技术向数字化、信息化建设迈进。以前企业对于博客信息的管理和控制,采用人工登记的方式保存相关数据,这种以人力为主的管理模式已然落后。本人结合使用主流的程序开发技术,设计了一款基于Springboot开发的精简博客系统,可以较大地减少人力、财力的损耗,方便相关人员及时更新和保存信息。本系统主要使用B/S开发模式,在idea开发平台上,运用Java语言设计相关的系统功能模块,MySQL数据库管理相关的系统数据信息,SpringBoot框架设计和开发系统功能架构,最后通过使用Tomcat服务器,在浏览器中发布设计的系统,并且完成系统与数据库的交互工作。本文对系统的需求分析、可行性分析、技术支持、功能设计、数据库设计、功能测试等内容做了较为详细的介绍,并且在本文中也展示了系统主要的功能模块设计界面和操作界面,并对其做出了必要的解释说明,方便用户对系统进行操作和使用,以及后期的相关人员对系统进行更新和维护。本系统的实现可以极大地提高企业的工作效率,提升用户的使用体验,因此在现实生活中运用本系统具有很大的使用价值。 关键词:博客管理;Java语言;B/S结构;MySQL数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值