题目大意:

求出字典序最小,重复次数最多,的子串。

思路分析:

RMQ + height 数组可以求出任意两个后缀的lcp

我们枚举答案字符串的重复的长度。

如果这个字符串的长度为 l ,而且这个字符串出现过两次或两次以上

那么你会发现在原串中  str[0] str[l] str[2*l] ....肯定有相邻的两个被包含在重复的串中。

我们求出这两个相邻的后缀的lcp

我们上面仅仅说的是被包含在重复的串中,但并不一定就是以 str[0], str[l],str[2*l]....为起点的。

那我们就要往前去寻找这个起点。

也不是往前枚举,可以发现只要往前移动  l-lcp%l 个位置。

比如。

xbcabcab

当 l = 3 的时候

你找到了

ab

abcab

发现 lcp = 2,然后往前减去一个 l-lcp%l ,结果cab和cabcab的lcp 变成了3

也就是说往前寻找可以再补齐一个周期。

再讨论字典序最小的问题。

在sa中找到的第一个,满足最长的重复次数和长度的也就是字典序最小的了。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define maxn 100005
using namespace std;char str[maxn];
int sa[maxn],t1[maxn],t2[maxn],c[maxn],n;
void suffix(int m)
{int *x=t1,*y=t2;for(int i=0; i<m; i++)c[i]=0;for(int i=0; i<n; i++)c[x[i]=str[i]]++;for(int i=1; i<m; i++)c[i]+=c[i-1];for(int i=n-1; i>=0; i--)sa[--c[x[i]]]=i;for(int k=1; k<=n; k<<=1){int p=0;for(int i=n-k; i<n; i++)y[p++]=i;for(int i=0; i<n; i++)if(sa[i]>=k)y[p++]=sa[i]-k;for(int i=0; i<m; i++)c[i]=0;for(int i=0; i<n; i++)c[x[y[i]]]++;for(int i=0; i<m; i++)c[i]+=c[i-1];for(int i=n-1; i>=0; i--)sa[--c[x[y[i]]]]=y[i];swap(x,y);p=1;x[sa[0]]=0;for(int 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;}
}
int rank[maxn],height[maxn];
void getheight()
{int k=0;for(int i=0; i<n; i++)rank[sa[i]]=i;for(int i=0; i<n; i++){if(k)k--;if(!rank[i])continue;int j=sa[rank[i]-1];while(str[i+k]==str[j+k])k++;height[rank[i]]=k;}
}int f[maxn][30];void RMQINIT()
{for(int i=0;i<n;i++)f[i][0]=height[i];for(int j=1;(1<<j)<=n;j++)for(int i=0;i+(1<<j)-1<n;i++)f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}int RMQ(int l,int r)
{if(l>r)swap(l,r);l++;int k=floor(log(r-l+1.0)/log(2.0));return min(f[l][k],f[r+1-(1<<k)][k]);
}
int ans[maxn];
int main()
{int cas=1;while(scanf("%s",str)!=EOF && str[0]!='#'){n=strlen(str);str[n]=0;n++;suffix(128);getheight();RMQINIT();int Max=0;int top=0;for(int l=1;l<n;l++){for(int i=l;i<n;i+=l){int lcp=RMQ(rank[i-l],rank[i]);int repeat = lcp/l+1;int st = i-(l-lcp%l);if(st>=l && lcp%l){if(RMQ(rank[st-l],rank[st])>=lcp)repeat++;}if(repeat>Max){Max=repeat;top=0;ans[top++]=l;}else if(repeat==Max)ans[top++]=l;}}int len=-1,st;for(int i=1;i<n && len==-1;i++)for(int j=0;j<top;j++){if(RMQ(rank[sa[i]],rank[sa[i]+ans[j]])>=(Max-1)*ans[j]){len=ans[j];st=sa[i];break;}}printf("Case %d: ",cas++);for(int i=st;i<st+len*Max;i++)printf("%c",str[i]);puts("");}return 0;
}

POJ 3693 Maximum repetition substring (后缀数组)相关推荐

  1. POJ - 3693 Maximum repetition substring(后缀数组+RMQ)

    题目链接:点击查看 题目大意:给出一个字符串,求出字符串中 重复次数最多的连续重复子串 ,如果有多个答案,输出字典序最小的 题目分析:又是一个模板题,这里放一个大佬的博客,讲的很清楚: https:/ ...

  2. POJ-3693 Maximum repetition substring 后缀数组

    题目链接:http://poj.org/problem?id=3693 求字符串的重复次数最多的且字典序最小的字串. 很不错的题目.罗穗骞大牛论文的模板题,摘了Neo / Add ~0U>> ...

  3. 牛客-139 I. Substring(后缀数组 or 后缀自动机)

    牛客-139 I. Substring(后缀数组 or 后缀自动机) 题目链接 题意 一个由{a,b,c}\{a, b, c\}{a,b,c}组成的字符串SSS,求S子串的最大的集合,使得集合里的字符 ...

  4. POJ3693 Maximum repetition substring

    题目 The repetition number of a string is defined as the maximum number R such that the string can be ...

  5. HDU 5769 Substring(后缀数组)

    Substring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total ...

  6. HDU - 5769 Substring(后缀数组)

    题目链接:点击查看 题目大意:给出一个字符串 s 和一个字符 ch,问字符串 s 中有多少个本质不同的子串包含字符 ch 题目分析:其实就是求本质不同的子串加了一点条件,对于每个sa[ i ],其本质 ...

  7. POJ - 3261 Milk Patterns(二分+后缀数组)

    题目链接:点击查看 题目大意:给出一个字符串,以及一个k,现在求出现次数大于等于k次的最大可重叠子串的长度 题目分析:可以说是后缀数组的模板题目了吧..直接跑出height数组,因为height数组代 ...

  8. POJ - 3450 Corporate Identity(二分+后缀数组)

    题目链接:点击查看 题目大意:给出n个字符串,求出n个字符串中最长的公共子串,如果没有,输出IDENTITY LOST 题目分析:可以直接用二分+后缀数组来做,先将n个字符串连接起来,中间用一个不同的 ...

  9. POJ - 2774 Long Long Message(后缀数组)

    题目链接:点击查看 题目大意:给出两个字符串,求出其最长的公共子串 题目分析:后缀数组水题,直接用一个不同的符号拼接一下两个字符串,然后跑出height数组和sa数组,再遍历一遍取最大值就是答案了,需 ...

最新文章

  1. IOS UI 代码创建UIButton,UITextField,UILabel
  2. 跨平台PHP调试器设计及使用方法——高阶封装
  3. 人的寿命可能与智商成正比
  4. 解决C#导出excel异常来自 HRESULT:0x800A03EC的方法 .
  5. 4.9 内容代价函数-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
  6. Atom + Texlive 配置
  7. FreeBSD 9.1安装KMS 这是一个伪命题###### ,9....
  8. 【数据结构与算法】之深入解析“分数加减运算”的求解思路与算法示例
  9. 如此接私活So easy:给开发者,PM,设计师
  10. C++语言程序设计上机指导(二级),C++语言程序设计上机指导(二级)
  11. 好久以来,就想为你写一首诗
  12. springboot 前缀_springboot搭配thymeleaf访问html页面的时候,什么时候需要自定义前缀和后缀呢...
  13. 在几何画板中如何制作圆柱的侧面展开动画_几何画板制作圆锥侧面展开图课件...
  14. 网络规划设计师教程知识点精讲之计算机网络分类
  15. linux超时设置函数,I/O操作上设置超时之alarm闹钟法
  16. Aruba 无线调试(Instant AP)
  17. 优秀的汽车后市场门店应该具备的数字化能力
  18. 数据分析师的能力和目标的个人总结
  19. dlink中设置端口映射图文讲解(解决电驴tcp链接测试失败问题)
  20. iOS篇—Demo5—时钟

热门文章

  1. 车辆网络安全ISO/SAE 21434解读(十)TARA分析
  2. 使用jedis连接redis,关闭连接问题
  3. TCP的三次握手与四次挥手
  4. js获取最近12个月的时间
  5. 苹果app老是显示无法连接服务器失败原因,iphone无法连接到app store服务器出错怎么办...
  6. 魅族l681q详细开启Usb调试模式的步骤
  7. 超微服务器主板ipmi证书,超微主板的服务器使用IPMI远程安装操作系统教程
  8. 解决Post请求中文乱码问题
  9. 【git】git下拉项目Pulling is not possible because you have unmerged files解决方案
  10. 对比两个自定义对象是否相等