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 ...
随机推荐
- Python 实现双端队列 Deque
操作 Deque() 创建一个空的双端队列 add_front(item) 从队头加入一个item元素 add_rear(item) 从队尾加入一个item元素 remove_front() 从队头删 ...
- nyoj 矩形个数
矩形的个数 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 在一个3*2的矩形中,可以找到6个1*1的矩形,4个2*1的矩形3个1*2的矩形,2个2*2的矩形,2个3 ...
- Crontab定时备份数据库
1.创建一个shell脚本文件 cd /usr mkdir dbbackup cd /usr/dbbackup vim backup.sh echo "------------------- ...
- MHA 安装与简单使用
MHA 在过去几年一直用的比较火,特别是在在传统复制的那个年代.至从有了GTID好像我们也可以把MHA给忘记了,但是很多企业现在还是在用的比较多.每个公司的MHA玩法也不太一样,但是本质都是差不多了. ...
- Linux入门:vi 和 vim
vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器. 本文介绍了vi (vim)的基本使用方法,但对于普通用户来说基本上够了! 转自:http://www.l ...
- ELK学习总结(2-4)bulk 批量操作-实现多个文档的创建、索引、更新和删除
bulk 批量操作-实现多个文档的创建.索引.更新和删除 ----------------------------------------------------------------------- ...
- GIT入门笔记(4)- GIT 安装
关于Windows下的安装工具-msysgit Windows下要使用很多Linux/Unix的工具时,需要Cygwin这样的模拟环境,Git也一样. Cygwin的安装和配置都比较复杂,不建议直接折 ...
- spring boot 中active的profile会和标准配置合并吗
如下图,两个profile配置文件,一个默认的(application.properties),一个是test的. 活跃配置为test. spring.profiles.active=test ste ...
- python 类的进阶
类的进阶 一 isinstance(obj,cls)和issubclass(sub,super) class Foo: def __init__(self,name): self.name = nam ...
- API验证及AES加密
API验证 API验证: a. 发令牌: 静态 PS: 隐患 key被别人获取 b. 动态令牌 PS: (问题越严重)用户生成的每个令牌被黑客获取到,都会破解 c. 高级版本 PS: 黑客网速快,会窃 ...