题目:Maximum repetition substring

链接:http://acm.hdu.edu.cn/showproblem.php?pid=2459

题意:给你一个字符串,求连续重复出现次数最多的子串(不重叠),如果有多个,输出字典序最小的那个。别如aacdabcdab,a连续着重复出现2次,cdab连续着出现2次,但aa的字典序小,所以输出aa。

思路:

  枚举+后缀树组+rmq

  枚举重复串的长度,后缀数组预处理出height数组,rmq预处理height,实现O(1)查询。

  给几组测试数据:

  1. aabababa,答案为ababab,不是bababa

  2. atbctbctb,答案是bctbct,不是ctbctb

  3. aabcabcabcab,答案是abcabcabc,不是cabcabcab

 #include<stdio.h>
#include<string.h>
#include<math.h>
#define N 200020
char s1[];
int ws[N],wv[N];
int sa[N],r[N],wx[N],wy[N];
int height[N];
bool cmp(int *r,int a,int b,int l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void da(int *r,int n,int m)
{
//注意,这里的n必须比原始数组大小大1
int *x=wx,*y=wy;
for(int i=;i<m;i++) ws[i]=;
for(int i=;i<n;i++) ws[x[i]=r[i]]++;
for(int i=;i<m;i++) ws[i]+=ws[i-];
for(int i=n-;i>=;i--) sa[--ws[x[i]]]=i;
//这里的x[i] 表示下标i的第一关键字排名
int i,j,p,*t;
for(j=,p=;p<n;j*=,m=p)
{
for(p=,i=n-j;i<n;i++) y[p++]=i;
for(i=;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
//此时的y[i] 表示第二关键字排第i的下标是y[i]
for(i=;i<n;i++) wv[i]=x[y[i]];
for(i=;i<m;i++) ws[i]=;
for(i=;i<n;i++) ws[wv[i]]++;
for(i=;i<m;i++) ws[i]+=ws[i-];
for(i=n-;i>=;i--) sa[--ws[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i],sa[i-],j)?p-:p++;
}
for(int i=;i<n;i++)
{
r[sa[i]]=i;
}
}
void calHeight(int n)
{
int h=;
for(int i=;i<n;i++)
{
if(r[i]==) h=;
else
{
int k=sa[r[i]-];
if(--h<) h=;
while(s1[k+h]==s1[i+h]) h++;
}
height[r[i]]=h;
}
}
int f[][];
int min(int x,int y)
{
return x<y?x:y;
}
int max(int x,int y)
{
return x<y?y:x;
}
void rmq(int n)
{
for(int j=;j<n;j++) f[j][]=height[j];
for(int i=;i<;i++)
{
for(int j=;j<n;j++)
{
if(j+(<<i)- < n)
{
f[j][i]=min(f[j][i-],f[j+(<<i-)][i-]);
}
}
}
}
int look(int x,int y)
{
x=r[x];
y=r[y];
if(x>y) x^=y^=x^=y;
x++;
int k=(int)log2((double)(y-x+));
return min(f[x][k],f[y-(<<k)+][k]);
} bool cmp(int sl,int l)
{
if(r[sl]>r[l]) return ;
return ;
} void solve(int n)
{
int maxt=,sl=,sr=;
for(int i=;i<=n/;i++)
{
for(int j=;j+i<n;j+=i)
{
int l=j;
int r=j+i;
int lcp=look(l,r);
int d=lcp/i+;
int t=j-(i-lcp%i);
for(int k=l-;k>=&&k+i>j&&s1[k]==s1[k+i];k--)
{
if(k==t)
{
d++;
l=k;
}
else if(cmp(l,k))
{
l=k;
}
}
if(d>maxt)
{
sl=l;
sr=l+d*i-;
maxt=d;
}
else if(d==maxt&&cmp(sl,l))
{
sl=l;
sr=l+d*i-;
}
}
}
for(int i=sl;i<=sr;i++)
{
printf("%c",s1[i]);
}
printf("\n");
} int main()
{
int cas=;
while(scanf("%s",s1)!=EOF)
{
if(s1[]=='#') break;
int len=strlen(s1);
for(int i=;i<len;i++)
r[i]=s1[i]-'a'+;
r[len++]=;
da(r,len,);
calHeight(len);
rmq(len);
printf("Case %d: ",cas++);
solve(len-); }
return ;
}

HDU 2459 Maximum repetition substring的更多相关文章

  1. 【HDOJ】2459 Maximum repetition substring

    后缀数组+RMQ. /* 2459 */ #include <iostream> #include <sstream> #include <string> #inc ...

  2. POJ3693 Maximum repetition substring [后缀数组 ST表]

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9458   Acc ...

  3. Maximum repetition substring 后缀数组

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7578   Acc ...

  4. Maximum repetition substring (poj3693 后缀数组求重复次数最多的连续重复子串)

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6328   Acc ...

  5. POJ 3693 Maximum repetition substring(最多重复次数的子串)

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10461   Ac ...

  6. POJ3693 Maximum repetition substring —— 后缀数组 重复次数最多的连续重复子串

    题目链接:https://vjudge.net/problem/POJ-3693 Maximum repetition substring Time Limit: 1000MS   Memory Li ...

  7. POJ3693 Maximum repetition substring 后缀数组

    POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...

  8. Maximum repetition substring(POJ - 3693)(sa(后缀数组)+st表)

    The repetition number of a string is defined as the maximum number \(R\) such that the string can be ...

  9. POJ 3693 Maximum repetition substring(后缀数组)

    Description The repetition number of a string is defined as the maximum number R such that the strin ...

随机推荐

  1. 【Linux常见问题】SecureCRT 终端连接密钥交换失败错误

    SecureCRT 终端软件连接linux操作系统,出现如下错误: 英文描述:Key exchange failed. No compatible key exchange method. The s ...

  2. Angular 开发小妙招1:提交表单数据验证不通过,更改输入组件的样式

    开发表单时,客户端数据完整性校验是必不可少的,在jquery 时代出现了无数的数据验证插件也很好用,开发Angular 应用时,angular 内置了一些常用的数据验证指令.今天要讲的不是这些指令如何 ...

  3. react中使用Ajax请求(axios,Fetch)

    React本身只关注于界面, 并不包含发送ajax请求的代码,前端应用需要通过ajax请求与后台进行交互(json数据),可以使用集成第三方ajax库(或自己封装) 常用的ajax请求库 jQuery ...

  4. python requests提示警告InsecureRequestWarning

    在Python3中使用以下代码报错: import requests response = requests.get(url='', verify=False) 错误代码如下: InsecureReq ...

  5. mongodb查询的语法(大于,小于,大于或等于,小于或等于等等)

    1 ) . 大于,小于,大于或等于,小于或等于 $gt:大于$lt:小于$gte:大于或等于$lte:小于或等于 例子: db.collection.find({ "field" ...

  6. jenkins忘记管理员密码之解决方案

    jenkins忘记管理员密码怎么办? 通常有这么几种解决方案,如下所示: (1)进入对应的用户目录文件夹,以ubuntu16.04为例,jenkins安装目录为/var/lib/jenkins进入到该 ...

  7. # 20175329 2018-2019-2 《Java程序设计》第二周学习总结

    # 学号 2018-2019-3<Java程序设计>第三周学习总结 ## 教材学习内容总结 第二三章与我们所学习的C语言有很多的相似点,在这里我想主要就以我所学习的效果来讨论一下JAVA与 ...

  8. VMware 中安装虚拟机和宿主机通信

    网络上对于三种连接模式说的很多了,这里就不在具体的说明了.此处采用的NAT模式连接虚拟机,让虚拟机和宿主机互相通讯,并且让虚拟机能访问互联网. 1.首先设置虚拟机的网络,如下图.通过如下操作进入虚拟机 ...

  9. EF Core中,通过实体类向SQL Server数据库表中插入数据后,实体对象是如何得到数据库表中的默认值的

    我们使用EF Core的实体类向SQL Server数据库表中插入数据后,如果数据库表中有自增列或默认值列,那么EF Core的实体对象也会返回插入到数据库表中的默认值. 下面我们通过例子来展示,EF ...

  10. Insider Dev Tour(2018.06.28)

    时间:2018.06.28地点:北京金茂万丽酒店