POJ 3693 Maximum repetition substring RMQ+后缀数组
来源:互联网 发布:php is_string 编辑:程序博客网 时间:2024/05/18 00:38
The repetition number of a string is defined as the maximum number R such that the string can be partitioned intoR 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.
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 '#'.
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.
ccabababcdaabbccaa#
Case 1: abababCase 2: aa
题意:给你一个串,让你求出重复次数最多的连续重复子串,若有多个则输出字典序最小的那个
思路:
官方题解
我自己的理解:
首先枚举重复串的长度l,如果重复度大于1原串中st[0],st[l],st[2*l]...中一定存在两个连续相等的情况,假如st[i*l]=st[(i+1)*l],则再分两步走
1.首先先求出两者对应后缀串的最大前缀,这样就能确定末尾
2,然后从这两个元素向前匹配,知道不能再匹配为止,这样就能确定开头
注意在判断的时候如果枚举的l对应好几种情况则选择rank最小的
3.在确定两个后缀的最大前缀时,需要用到求在一段区间内height数组的最小值,这时需要用到RMQ算法 预处理一下在直接查找即可
ac代码:
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>using namespace std;const int N=2*100100;int cl,rk[N],sa[N],Rs[N],y[N],wr[N],h[N],r[N][30];char c[N];int minn(int x,int y){return x<y ? x:y;}void get_sa(int m){ for(int i=1;i<=cl;i++) rk[i]=c[i]-'a'+1; for(int i=1;i<=m;i++) Rs[i]=0; for(int i=1;i<=cl;i++) Rs[rk[i]]++; for(int i=1;i<=m;i++) Rs[i]+=Rs[i-1]; for(int i=cl;i>=1;i--) sa[Rs[rk[i]]--]=i; int ln=1,p=0; while(p<cl) { int k=0; for(int i=cl-ln+1;i<=cl;i++) y[++k]=i; for(int i=1;i<=cl;i++) if(sa[i]>ln) y[++k]=sa[i]-ln; for(int i=1;i<=cl;i++) wr[i]=rk[y[i]]; for(int i=1;i<=m;i++) Rs[i]=0; for(int i=1;i<=cl;i++) Rs[wr[i]]++; for(int i=1;i<=m;i++) Rs[i]+=Rs[i-1]; for(int i=cl;i>=1;i--) sa[Rs[wr[i]]--]=y[i]; for(int i=1;i<=cl;i++) wr[i]=rk[i]; for(int i=cl+1;i<=cl+ln;i++) wr[i]=0; p=1;rk[sa[1]]=1; for(int i=2;i<=cl;i++) { if(wr[sa[i]]!=wr[sa[i-1]] || wr[sa[i]+ln]!=wr[sa[i-1]+ln]) p++; rk[sa[i]]=p; } ln*=2,m=p; } sa[0]=0,rk[0]=0;}void get_h(){ int k=0,j; for(int i=1;i<=cl;i++) if(rk[i]!=1) { j=sa[rk[i]-1]; if(k) k--; while(c[j+k]==c[i+k] && j+k<=cl && i+k<=cl) k++; h[rk[i]]=k; } h[1]=0;}void get_rmq(){ for(int i=1;i<=cl;i++) r[i][0]=h[i]; for(int j=1;(1<<j)<=cl;j++) for(int i=1;i+(1<<j)-1<=cl;i++) { r[i][j]=minn(r[i][j-1],r[i+(1<<(j-1))][j-1]); }}int query_rmq(int i,int j){ if(i>j) swap(i,j); i++; int k=0; while(i+(1<<(k+1)) <= j) k++; return minn(r[i][k],r[j-(1<<k)+1][k]);}int main(){ int x,y,z,t0,t1,now,ans,al,ar,T=0; while(1) { scanf("%s",c+1); cl=strlen(c+1); if(cl==1 && c[1]=='#') return 0; printf("Case %d: ",++T); get_sa(30); get_h(); get_rmq(); ans=0;al=ar=0; for(int L=1;L*2<=cl;L++) { for(int i=0;L*(i+1)+1<=cl;i++) { x=L*i+1,y=L*(i+1)+1; if(c[x]!=c[y]) continue; z=query_rmq(rk[x],rk[y]); t1=y+z-1; t0=0; for(int j=0;j<=L-1;j++)//往前匹配 { if(x-j<1 || c[x-j]!=c[y-j]) break; t0=x-j; now=((t1-t0+1)/L); if(now>ans || (now==ans && rk[t0]<rk[al])) ans=now,al=t0,ar=t0+now*L-1; } } } if(ans==0) printf("%c\n",c[sa[1]]); else { for(int i=al;i<=ar;i++) printf("%c",c[i]);printf("\n"); } } return 0;}
- POJ 3693 Maximum repetition substring(RMQ+后缀数组)
- poj 3693 Maximum repetition substring 后缀数组+RMQ
- POJ 3693 Maximum repetition substring 后缀数组 暴力 rmq
- POJ 3693 Maximum repetition substring 后缀数组 + RMQ预处理
- POJ 3693 Maximum repetition substring后缀数组加上RMQ
- poj 3693 Maximum repetition substring (后缀数组+RMQ)
- POJ 3693 Maximum repetition substring RMQ+后缀数组
- POJ 3693 Maximum Repetition Substring <后缀数组 + RMQ>
- poj 3693 Maximum repetition substring //后缀数组
- poj 3693 Maximum repetition substring (后缀数组)
- poj 3693 Maximum repetition substring(后缀数组)
- poj 3693 Maximum repetition substring(后缀数组)
- 【后缀数组】【poj 3693】Maximum repetition substring
- POJ 3693 Maximum Repetition Substring 后缀数组
- poj3693 Maximum repetition substring 后缀数组+RMQ
- POJ3693:Maximum repetition substring(后缀数组+RMQ)
- poj3693 Maximum repetition substring (后缀数组+rmq)
- HDU 2459 PKU 3693 Maximum repetition substring 后缀数组 RMQ
- WEB-XML&Tomcat
- AngularJS入门之如何快速上手(详细讲解什么是angular)
- 产品经理的素质能力模型
- iOS倒计时的实现,显示剩余天、时、分、秒
- Web Service学习小结——JAX-WS CXF AXIS2关系
- POJ 3693 Maximum repetition substring RMQ+后缀数组
- STM32Cube 简单实验的翻译
- 每天一个linux命令:grep 命令
- iOS实现倒计时显示 时 分 秒
- css1.15
- lua 二进制和八进制字符串互转
- 每天一个linux命令:wc命令
- Zigbee+SIM900A 通过http协议实现上传数据到云服务器
- css1.16