Maximum repetition substring POJ
来源:互联网 发布:论文写作的意义 知乎 编辑:程序博客网 时间:2024/06/06 05:41
题意:
给定一个字符串,求这个字符串的一个子串,满足子串是循环节循环次数最多的子串,在循环次数相同的时候输出字典序最小的字符串
思路:
参考国家集训队论文算法合集之《后缀数组——处理字符串的有力工具》
首先我们考虑枚举子串的循环节的长度L,我们只考虑循环至少两次的子串,那么可以知道这个子串至少长度为2L,同时如果我们把原串按照0,L,2L,3L,….,iL,(i+1)L,…来划分,那么这个子串可能会覆盖了iL,(i+1)L,假设这个i是满足条件的最小的i,那么我们现在要做的就是找到这个子串的起点是在哪里,可以知道这个起点应该是在[max(0,(i-1)L+1),iL]这个范围内,我们先求出LCP(suffix[iL],suffix[(i+1)L]),然后就不断往左边匹配str[iL-k],str[(i+1)L-k],每遇到一个可以匹配的k,我们知道它都可能是起点,而我们需要找的是在重复次数相同的情况下,字典序最小的子串,所以这些起点都要考虑进去才不会把字典序最小这个条件给遗漏了,然后我们知道这个起点s可以匹配s+L的后缀LCP(suffix[iL],suffix[(i+1)L])+k个字符,然后这里的重复次数就是这个匹配的字符个数/L+1,然后更新答案即可
代码:
#define debug printf#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<queue>#include<vector>#include<cmath>using namespace std;const int maxn=200000+100;int kase=0;void solve();char str[maxn];struct SuffixArray{ int s[maxn]; int sa[maxn]; int ran[maxn]; int height[maxn]; int t[maxn],t2[maxn],c[maxn]; int n; void clear() { n=0;memset(sa,0,sizeof(sa)); } void build_sa(int m) { int i,*x=t,*y=t2; for(i=0;i<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[i]=s[i]]++; for(i=1;i<m;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i; for(int k=1;k<=n;k<<=1){ int p=0; for(i=n-k;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k; for(i=0;i<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[y[i]]]++; for(i=1;i<m;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1;x[sa[0]]=0; for(i=1;i<n;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; if(p>=n) break; m=p; } } void build_height() { int i,j,k=0; for(i=0;i<n;i++){ ran[sa[i]]=i; } for(i=0;i<n;i++){ if(k) k--; j=sa[ran[i]-1]; while(s[i+k]==s[j+k]) k++; height[ran[i]]=k; } }};SuffixArray sa;void add(int ch){ sa.s[sa.n++]=ch;}void RMQ_init(int * A,int n);int RMQ(int L,int R);int main(){ kase=0; while(~scanf("%s",str)){ kase++; if(strcmp(str,"#")==0) break; solve(); } return 0;}void solve(){ sa.clear(); int len=strlen(str); for(int j=0;j<len;j++){ add(str[j]-'a'+1); } add(0); sa.build_sa(27); sa.build_height(); RMQ_init(sa.height,sa.n);// for(int i=0;i<sa.n;i++){// debug("hh%d %d\n",i,sa.sa[i]);// } int ans,lef,righ; ans=1; lef=righ=0; for(int L=1;L<=len;L++){// debug("%d\n",L); int K; int p,q; for(int i=0;((i+1)*L)<len;i++){ char x=str[i*L],y=str[(i+1)*L]; if(x!=y) continue; int ql,qr; ql=sa.ran[i*L],qr=sa.ran[(i+1)*L]; if(ql>qr) swap(ql,qr); ql++; K=RMQ(ql,qr);// debug("%d %d %d\n",L,i,K); p=(i*L),q=((i+1)*L); int bound=max(0,(i-1)*L+1); int res=(K/L)+1;// p++; if(res>ans||(res==ans&&sa.ran[p]<sa.ran[lef])){ ans=res; lef=p; righ=p+res*L; } p--;q--; while(p>=bound&&str[p]==str[q]){ K++;// debug("%d\n",K); int res=(K/L)+1;// p++; if(res>ans||(res==ans&&sa.ran[p]<sa.ran[lef])){ ans=res; lef=p; righ=p+res*L; } p--;q--; } } } printf("Case %d: ",kase);// righ=ans+lef; if(ans==1){ char maxv='z'; for(int i=0;i<len;i++){ if(str[i]<maxv){ maxv=str[i]; } } printf("%c\n",str[sa.sa[1]]); return; } for(int i=lef;i<righ;i++){ printf("%c",str[i]); } printf("\n");}int d[maxn][20];void RMQ_init(int * A,int n){ for(int i=0;i<n;i++){ d[i][0]=A[i];// debug("%d %d\n",i,A[i]); } for(int j=1;(1<<j)<=n;j++){ for(int i=0;i+(1<<j)-1<n;i++){ d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]); } }}int RMQ(int L,int R){ int k=0; while((1<<(k+1))<=R-L+1) k++; return min(d[L][k],d[R-(1<<k)+1][k]);}/*zzbzbzbaccdbaccdbacbdbacbdxbcabcabedbeaabcabcabcabaccdaccaccddcacacaacadbabbabaabaabaabababaabaabaabaccabababcdaabbccaabcbcbabapedabacewqpzababaaa#*/
阅读全文
0 0
- Maximum repetition substring POJ
- Maximum repetition substring POJ
- 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
- POJ 3693Maximum 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(后缀数组)
- 【后缀数组】【poj 3693】Maximum repetition substring
- POJ 3693 Maximum repetition substring(好题)
- POJ 3693 Maximum Repetition Substring 后缀数组
- 「POJ 3693」Maximum repetition substring
- CSS中的清除浮动全总结
- Android 多进程对Application影响
- 回忆那时年轻的作品--模拟操作系统
- iOS 用其他应用程序打开文件功能如何实现的iOS开发
- Appium native hybrid webview混合操作及元素定位(14)
- Maximum repetition substring POJ
- 非线性SVM与核函数
- Python多线程--(3)同步
- spring注解 -----最简单的注解与自动装配例子
- 数据库语句汇总
- Java内存模型
- 数据结构实验之栈二:一般算术表达式转换成后缀式
- MySQL初次安装修改密码
- flex-box弹性布局