POJ 3693 Maximum repetition substring ——后缀数组
重复次数最多的字串,我们可以枚举循环节的长度。
然后正反两次LCP,然后发现如果长度%L有剩余的情况时,答案是在一个区间内的。
所以需要找到区间内最小的rk值。
两个后缀数组,四个ST表,$\Theta(n\log n)$
就可以解决了
空间卡死了,瞎晶胞卡过去了。
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define mp make_pair
#define maxn 200010
#define inf 0x3f3f3f3f int _log[maxn],kas=0; struct Suffix_Array{
int s[maxn];
int cnt[maxn],sa[maxn],tmp[maxn],rk[maxn],h[maxn];
int st[2][maxn][18];
void build(int n,int m)
{
s[n]=0; n++; int i,j,k;
F(i,0,n+2) sa[i]=tmp[i]=rk[i]=h[i]=0;
F(i,0,m-1) cnt[i]=0;
F(i,0,n-1) cnt[rk[i]=s[i]]++;
F(i,1,m-1) cnt[i]+=cnt[i-1];
F(i,0,n-1) sa[--cnt[rk[i]]]=i;
for (k=1;k<=n;k<<=1)
{
F(i,0,n-1)
{
int j=sa[i]-k;
if (j<0) j+=n;
tmp[cnt[rk[j]]++]=j;
}
sa[tmp[cnt[0]=0]]=j=0;
F(i,1,n-1)
{
if (rk[tmp[i]]!=rk[tmp[i-1]]||rk[tmp[i]+k]!=rk[tmp[i-1]+k]) cnt[++j]=i;
sa[tmp[i]]=j;
}
memcpy(rk,sa,n*sizeof(int));
memcpy(sa,tmp,n*sizeof(int));
if (j>=n-1) break;
}
for (int i=k=0;i<n;h[rk[i++]]=k)
for (k?k--:0,j=sa[rk[i]-1];s[i+k]==s[j+k];k++);
F(i,0,n-1) st[0][i][0]=h[i];
F(i,1,17) F(j,0,n-(1<<i)) st[0][j][i]=min(st[0][j][i-1],st[0][j+(1<<(i-1))][i-1]);
F(i,0,n-1) st[1][i][0]=rk[i];
F(i,1,17) F(j,0,n-(1<<i)) st[1][j][i]=min(st[1][j][i-1],st[1][j+(1<<(i-1))][i-1]);
}
int query(int id,int l,int r)
{
int k=_log[r-l+1];
return min(st[id][l][k],st[id][r-(1<<k)+1][k]);
}
int lcp(int a,int b)
{
int aa=rk[a],bb=rk[b];
return query(0,min(aa,bb)+1,max(aa,bb));
}
}SA,SB; int ansl,ansr,mx,ans,n,minn;char s[maxn]; void solve(int L)
{
for (int i=0;i+L<n;i+=L)
if (s[i]==s[i+L])
{
int l=SA.lcp(i+1,i+L+1),r=SB.lcp(n-i-1,n-i-L-1);
if (l+r<L) continue;
if ((l+r)/L+1>mx) mx=(l+r)/L+1,ans=inf;
if ((l+r)/L+1==mx)
{
int tmp=SA.query(1,i-r+1,i-r+1+(l+r)%L);
if (tmp<ans)
{
ans=tmp;
ansl=SA.sa[tmp]; ansr=ansl+mx*L-1;
}
}
}
} int main()
{
F(i,2,maxn-1) _log[i]=_log[i>>1]+1;
while (scanf("%s",s)!=EOF&&s[0]!='#')
{
ansl=ansr=0,mx=0;minn=inf;
printf("Case %d: ",++kas);
mx=0;
n=strlen(s);
F(i,0,n-1)
{
SA.s[i]=s[i]-'a'+1;
SB.s[i]=s[n-i-1]-'a'+1;
minn=min(minn,(int)s[i]);
}
SA.s[n]=SB.s[n]=0;
SA.build(n,30); SB.build(n,30);
for (int i=1;i<=n;++i) solve(i);
if (mx==0) printf("%c\n",minn);
else
{
F(i,ansl,ansr) printf("%c",s[i]);
printf("\n");
}
}
}
POJ 3693 Maximum repetition substring ——后缀数组的更多相关文章
- poj 3693 Maximum repetition substring (后缀数组)
其实是论文题.. 题意:求一个字符串中,能由单位串repeat得到的子串中,单位串重复次数最多的子串.若有多个重复次数相同的,输出字典序最小的那个. 解题思路:其实跟论文差不多,我看了很久没看懂,后来 ...
- POJ 3693 Maximum repetition substring (后缀数组+RMQ)
题意:给定一个字符串,求其中一个由循环子串构成且循环次数最多的一个子串,有多个就输出最小字典序的. 析:枚举循环串的长度ll,然后如果它出现了两次,那么它一定会覆盖s[0],s[ll],s[ll*2] ...
- POJ3693 Maximum repetition substring 后缀数组
POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- POJ 3693 Maximum repetition substring(最多重复次数的子串)
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10461 Ac ...
- Maximum repetition substring 后缀数组
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7578 Acc ...
- POJ3693 Maximum repetition substring —— 后缀数组 重复次数最多的连续重复子串
题目链接:https://vjudge.net/problem/POJ-3693 Maximum repetition substring Time Limit: 1000MS Memory Li ...
- POJ 3693 Maximum repetition substring(后缀数组)
Description The repetition number of a string is defined as the maximum number R such that the strin ...
- POJ 3693 Maximum repetition substring(后缀数组+ST表)
[题目链接] poj.org/problem?id=3693 [题目大意] 求一个串重复次数最多的连续重复子串并输出,要求字典序最小. [题解] 考虑错位匹配,设重复部分长度为l,记s[i]和s[i+ ...
随机推荐
- sql语句执行碰到的问题
问题:传递给 LEFT 或 SUBSTRING 函数的长度参数无效 原因:在LEFT或SUBSTRING 中计算出来的长度是负数导致的 解决方法: 1)逐个排查法,2)先把语句执行一下,查看中断的地 ...
- P2421 A-B数对(增强版)
题目背景 woshiren在洛谷刷题,感觉第一题:求两数的和(A+B Problem)太无聊了,于是增加了一题:A-B Problem,难倒了一群小朋友,哈哈. 题目描述 给出N 个从小到大排好序的整 ...
- 使用JDK自带的jmap和jhat监控处于运行状态的Java进程
对于处于运行状态中的Java进程,JDK自带了很多工具,允许Java开发人员监控运行进程中的各种状态,比如该进程内部创建了多少个对象实例,消耗了多少内存,等等. 本文基于JDK1.8而写成. 我下面写 ...
- 关于js作用域问题详解
执行上下文 函数表达式和函数声明 1. console.log(a); // ReferenceError: a is not defined // ReferenceError(引用错误)对象表明一 ...
- KeyValuePair的使用
Dictionary<string, string> dc = new Dictionary<string, string>(); 前台页面: <div id=" ...
- Java递归获取部门树 返回jstree数据
@GetMapping("/getDept")@ResponseBodypublic Tree<DeptDO> getDept(String deptId){ Tree ...
- 一. python基础知识
第一章.变量与判断语句 1.第一个python程序 # -*- coding:utf-8 -*- # Author: Raymond print ("hello world") p ...
- Ukulele 那些花儿
- JS与IOS、安卓的交互
最近做的项目中涉及到了与安卓和ios的交互问题,对于一个新手来说,多多少少会有点迷糊.在调用安卓和ios的callback回调时,很轻松的就调用成功了,而且,步骤也不那么繁琐.刚开始,只知道那样使用可 ...
- (57)zabbix Slide shows幻灯片展示
定义好screen之后,我们想了解服务器状况之时,一般会一个个screen点过去,zabbix提供了幻灯片展示方法,可以定义多个Slide,一个slide中可以包含多个screen. 创建slide ...