poj 3693 后缀数组 重复次数最多的连续重复子串
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 8669 | Accepted: 2637 |
Description
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.
/*
poj 3693 后缀数组 重复次数最多的连续重复子串 给你一个字符串,求里面重复次数最多的字符串,卒
ccabababc -> ababab = 3 ababa = 1 表示论文里面的思路并没看懂,主要还是参考别人写好的代码的
首先,枚举l(用来重复的长度),判断suff[i],suff[i+l]
如果公共前缀k%l != 0,则说明这个长度不合适,修改后再进行判断。
于是考虑k%i,可以看成后面多了k%l个字符,但可以看成前面少了m = l-k%l
个字符,于是成了求 l-i-m,l-m的情况,再与之前的结果取较大值即可
然后记录最大次数cnt和符合条件的所有解a[] 最后进行判断,因为要求字典序最小,所以从sa[1]开始判断,如果
su[sa[i]]和su[sa[i]+a[j]]的公共前缀大于等于(cnt-1)*a[j]
则说明满足 hhh-2016-03-13 21:37:55
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <map>
using namespace std;
typedef long long ll;
typedef long double ld;
#define lson (i<<1)
#define rson ((i<<1)|1)
const int maxn = 100100; int t1[maxn],t2[maxn],c[maxn];
bool cmp(int *r,int a,int b,int l)
{
return r[a]==r[b] &&r[l+a] == r[l+b];
} void get_sa(int str[],int sa[],int Rank[],int height[],int n,int m)
{
n++;
int p,*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 j = 1; j <= n; j <<= 1)
{
p = 0;
for(int i = n-j; i < n; i++) y[p++] = i;
for(int i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i]-j;
for(int i = 0; i < m; i++) c[i] = 0;
for(int i = 0; i < n; i++) c[x[y[i]]]++ ;
for(int i = 1; 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]] = cmp(y,sa[i-1],sa[i],j)? p-1:p++;
if(p >= n) break;
m = p;
}
int k = 0;
n--;
for(int i = 0; i <= n; i++)
Rank[sa[i]] = i;
for(int i = 0; i < n; i++)
{
if(k) k--;
int j = sa[Rank[i]-1];
while(str[i+k] == str[j+k]) k++;
height[Rank[i]] = k;
}
} int mm[maxn];
int dp[20][maxn];
int Rank[maxn],height[maxn];
int sa[maxn],str[maxn];
char ts[maxn]; void ini_RMQ(int n)
{
mm[0] = -1;
for(int i = 1;i <= n;i++)
mm[i] = (((i & (i-1)) == 0) ? mm[i-1]+1:mm[i-1]); for(int i =1;i <= n;i++)
dp[0][i] = height[i];
for(int i = 1;i <= mm[n];i++)
{
for(int j = 1;j+(1<<i)-1 <= n;j++)
{
int a = dp[i-1][j];
int b = dp[i-1][j+(1<<(i-1))];
dp[i][j] = min(a,b);
}
}
} int askRMQ(int a,int b)
{
if(a > b) swap(a,b);
a++;
int t = mm[b-a+1];
b -= (1<<t)-1;
return min(dp[t][a],dp[t][b]);
}
int a[maxn];
int main()
{
int cas = 1;
while(scanf("%s",ts) != EOF)
{
if(ts[0] == '#')
break;
int len = strlen(ts);
for(int i = 0; i < len; i++)
str[i] = ts[i];
str[len] = 0;
printf("Case %d: ",cas++);
get_sa(str,sa,Rank,height,len,150);
ini_RMQ(len);
int cnt = 0,tot = 0;
for(int i = 1;i <= len;i++)
{
for(int j = i;j < len;j+=i)
{
int tk = askRMQ(Rank[j-i],Rank[j]);
int m = i - tk%i; if(j > i && tk%i) tk = max(tk,askRMQ(Rank[j-i-m],Rank[j-m]));
if(tk % i) tk = 0;
if(tk) tk = tk/i+1;
if(tk > cnt)
cnt = tk,tot=0,a[tot++]=i;
else if(tk == cnt && a[tot-1] != i)
a[tot++] = i;
}
}
// cout <<cnt <<endl;
int flag = 0;
for(int i = 1;i < len && !flag;i++)
{
for(int j = 0;j < tot && !flag;j++)
{
if(askRMQ(Rank[sa[i]],Rank[sa[i]+a[j]])>=a[j]*(cnt-1))
{
ts[sa[i]+a[j]*cnt] = '\0';
printf("%s\n",ts+sa[i]);
flag = 1;
}
}
}
}
return 0;
}
poj 3693 后缀数组 重复次数最多的连续重复子串的更多相关文章
- [poj 3693]后缀数组+出现次数最多的重复子串
题目链接:http://poj.org/problem?id=3693 枚举长度L,看长度为L的子串最多能重复出现几次,首先,能出现1次是肯定的,然后看是否能出现两次及以上.由抽屉原理,这个子串出现次 ...
- POJ - 3693 Maximum repetition substring(重复次数最多的连续重复子串)
传送门:POJ - 3693 题意:给你一个字符串,求重复次数最多的连续重复子串,如果有一样的,取字典序小的字符串. 题解: 比较容易理解的部分就是枚举长度为L,然后看长度为L的字符串最多连续出现 ...
- POJ-3693-Maximum repetition substring(后缀数组-重复次数最多的连续重复子串)
题意: 给出一个串,求重复次数最多的连续重复子串 分析: 比较容易理解的部分就是枚举长度为L,然后看长度为L的字符串最多连续出现几次. 既然长度为L的串重复出现,那么str[0],str[l],str ...
- 【POJ 3693】Maximum repetition substring 重复次数最多的连续重复子串
后缀数组的论文里的例题,论文里的题解并没有看懂,,, 求一个重复次数最多的连续重复子串,又因为要找最靠前的,所以扫的时候记录最大的重复次数为$ans$,扫完后再后从头暴力扫到尾找重复次数为$ans$的 ...
- spoj687 后缀数组重复次数最多的连续重复子串
REPEATS - Repeats no tags A string s is called an (k,l)-repeat if s is obtained by concatenating k& ...
- POJ3693 Maximum repetition substring —— 后缀数组 重复次数最多的连续重复子串
题目链接:https://vjudge.net/problem/POJ-3693 Maximum repetition substring Time Limit: 1000MS Memory Li ...
- SPOJ - REPEATS —— 后缀数组 重复次数最多的连续重复子串
题目链接:https://vjudge.net/problem/SPOJ-REPEATS REPEATS - Repeats no tags A string s is called an (k,l ...
- Repeats SPOJ - REPEATS(重复次数最多的连续重复子串)
论文题例8 https://blog.csdn.net/queuelovestack/article/details/53031731这个解释很好 其实,当枚举的重复子串长度为i时,我们在枚举r[i* ...
- Maximum repetition substring POJ - 3693(重复次数最多的连续重复子串)
这题和SPOJ - REPEATS 一样 代码改一下就好了 这个题是求这个重复子串,还得保证字典序最小 巧妙运用sa 看这个 https://blog.csdn.net/queuelovestack ...
随机推荐
- Angular组件——组件生命周期(一)
组件声明周期以及angular的变化发现机制 红色方法只执行一次. 变更检测执行的绿色方法和和组件初始化阶段执行的绿色方法是一个方法. 总共9个方法. 每个钩子都是@angular/core库里定义的 ...
- php抽象类和接口的区别
php抽象类和接口的区别 tags:抽象类 接口 抽象类和接口 php 引言:这是一个面试经常被问到的问题,也是一个经典问题.我们尽量引用官方权威的说明或者经过实验来证明本文所说的内容准确性. 抽象类 ...
- 彻底搞懂shell的高级I/O重定向
本文目录: 1.1 文件描述符(file description,fd) 1.2 文件描述符的复制 1.3 重定向顺序很重要:">file 2>&1"和&quo ...
- WPS怎么让前几页的页眉或者页脚与后面的不同
其实不管利用WPS还是office对文档还是PPT进行操作,其实核心思想还是一种编程,主要是前端的编程,就是通过改变一些这些软件设置的样式,然后通过改变这些样式,使这些文字以老师要求的格式显示出来的, ...
- CentOS 7 使用yum安装出现错误
CentOS 7 使用yum安装软件出现错误: Loaded plugins: fastestmirror 此错误信息可能是因为DNS配置错误,可以通过更改配置文件来解决: 1. 使用vi打开DNS的 ...
- c语言中宏定义和常量定义的区别
他们有共同的好处就是"一改全改,避免输入错误"哪两者有不同之处吗?有的. 主要区别就在于,宏定义是在编译之前进行的,而const是在编译阶段处理的 宏定义不占用内存单元而const ...
- python 字符串的方法
capitalize() 把字符串的第一个字符改为大写 casefold() 把整个字符串的所有字符改为小写 center(width) 将字符串居中,并使用空格填充至长度 width 的新字符串 c ...
- SpringBoot的重要特性
一.Web特性 Spring Boot 提供了spring-boot-starter-web来为Web开发予以支持,spring-boot-starter-web为我们提供了嵌入的Tomcat以及Sp ...
- Spring Security 入门(3-10)Spring Security 的四种使用方式
原文链接: http://www.360doc.com/content/14/0724/17/18637323_396779659.shtml 下面是作者的一个问题处理
- python--同步锁/递归锁/协程
同步锁/递归锁/协程 1 同步锁 锁通常被用来实现对共享资源的同步访问,为每一个共享资源创建一个Lock对象,当你需需要访问该资源时,调用acquire()方法来获取锁对象(如果其他线程已经获得了该锁 ...