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

之前hihocoder那题可以算出最多重复次数,但是没有输出子串。一开始以为只要基于那个,每次更新答案的时候按SA更新子串起始位置和长度就好了,但实际发现那个解法在计算重复次数的时候并不会遍历每一个合法串(比如daeaea,枚举长度为2时,只会计算eaea,漏了aeae)所以不能直接在计算过程中直接得出答案。

那难道又要退化成枚举每个起始位置了么?其实不然,我们可以记录答案支持的所有长度(这个数组不会太大),扫描SA,每个SA都枚举长度,一旦发现满足直接输出并结束,另外特判一下只出现一次的重复串(即ascii最小的单字符)。

#include <cstdio>
#include <string>
#include <iostream>
#include <set>
#include <algorithm>
#include <vector>
#include <map>
#include <cstring>
#include <queue>
#include <cmath>
#define LL int
using namespace std;
const LL N = ;
string s;
int lx[N];
class SF
{
//N:数组大小
public:
int x[N], y[N], c[N];
int Height[N], str[N], SA[N], Rank[N];//Height数组从2开始,SA记录Rank=i的下标
int slen;
int m;//字符集处理大小(传入如果不是数字,需要做位移转换)
bool cmp(int* r, int a, int b, int l)
{
return r[a] == r[b] && r[a + l] == r[b + l];
}
void Suffix(int n)
{
++n;
int i, j, p;
for (i = ; i < m; ++i) c[i] = ;
for (i = ; i < n; ++i) c[x[i] = str[i]]++;
for (i = ; i < m; ++i) c[i] += c[i - ];
for (i = n - ; i >= ; --i) SA[--c[x[i]]] = i;
for (j = ; j <= n; j <<= )
{
p = ;
for (i = n - j; i < n; ++i) y[p++] = i;
for (i = ; i < n; ++i) if (SA[i] >= j) y[p++] = SA[i] - j;
for (i = ; i < m; ++i) c[i] = ;
for (i = ; i < n; ++i) c[x[y[i]]]++; for (i = ; i < m; ++i) c[i] += c[i - ];
for (i = n - ; i >= ; --i) SA[--c[x[y[i]]]] = y[i]; swap(x, y);
p = ;
x[SA[]] = ;
for (i = ; i < n; ++i)
{
x[SA[i]] = cmp(y, SA[i - ], SA[i], j) ? p - : p++;
}
if (p >= n)break;
m = p;
} int k = ;
n--;
for (i = ; i <= n; ++i) Rank[SA[i]] = i;
for (i = ; i < n; ++i)
{
if (k)--k;
j = SA[Rank[i] - ];
while (str[i + k] == str[j + k])++k;
Height[Rank[i]] = k;
//cout << k << endl;
}
}
static const int bitlen = ;
LL lg2(LL p)//计算log2(n)
{
return (LL)(log(p) / log());
}
LL dp[bitlen][N];
LL bit[bitlen];
void initRMQ()//初始化
{
bit[] = ;
for (int i = ; i < bitlen; i++) bit[i] = * bit[i - ];
for (int i = ; i <= slen; i++)
dp[][i] = Height[i];
dp[][] = dp[][] = ;
for (LL i = ; bit[i] < slen + ; i++)
for (LL j = ; j + bit[i] <= slen + ; j++)
dp[i][j] = min(dp[i - ][j], dp[i - ][j + bit[i - ]]);
}
LL query(LL l, LL r)//查询两个Rank之间的lcp
{
if (r == l) return slen - SA[l];
if (l > r) swap(l, r);
l++;
LL mig = lg2(r - l + 1.0);
return min(dp[mig][l], dp[mig][r - bit[mig] + ]);
}
void init(string &s)
{
m=;
slen = s.size();
for (int i = ; i < slen; i++)
str[i] = s[i] - 'a' + ;//如果是字符,映射成从1开始的序列
str[slen] = ;//1作为结束符,防止越界
Suffix(slen);
initRMQ();
}
void solve()//cascnacnacdsdaj
{
int ans = ,al,st=-;
int cnt=;
set<char>fuck;
for(int i=; i<slen; i++)
fuck.insert(s[i]);
for (int len = ; len <= slen; len++)
{
for (int i = ; i+len< slen; i+=len)
{
int r1 = Rank[i], r2 = Rank[i+ len];
int lcp = query(r1, r2);
int sta=i;
if(ans<=lcp / len + )
{
if(ans<lcp / len + )
{
cnt=;
lx[cnt++]=len;
}
else lx[cnt++]=len;
ans=lcp / len + ;
} if (i - len + lcp%len >= )
{
sta=i - len + lcp%len;
if(sta==i-len)sta++;
lcp = query(Rank[sta], Rank[sta+len]);
if(ans<=lcp / len + )
{
if(ans<lcp / len + )
{
cnt=;
lx[cnt++]=len;
}
else lx[cnt++]=len;
ans=lcp / len + ;
}
}
}
}
int pos=-,lxl;
for(int i=; i<=slen; i++)
{
for(int j=;j<cnt;j++)
{
int sta=SA[i];
if(sta+lx[j]>=slen)break;
int rk=Rank[sta+lx[j]];
int lcp = query(i, rk);
if(ans==lcp / lx[j] + )
{
for(int i=; i<ans*lx[j]; i++)
cout<<s[i+sta];
cout<<endl;
goto li;
}
}
}
cout<<*fuck.begin()<<endl;
return;
li:
; }
} sf;
int main()
{
cin.sync_with_stdio(false);
//freopen("in.txt","r",stdin);
//freopen("o1.txt","w",stdout);
int cas=;
while (cin >> s)
{
if(s=="#")break;
cout<<"Case "<<cas++<<": ";
sf.init(s);
sf.solve();
}
return ;
}

POJ-3693/HDU-2459 Maximum repetition substring 最多重复次数的子串(需要输出具体子串,按字典序)的更多相关文章

  1. HDU 2459 Maximum repetition substring

    题目:Maximum repetition substring 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2459 题意:给你一个字符串,求连续重复出现 ...

  2. POJ - 3693 Maximum repetition substring(重复次数最多的连续重复子串)

    传送门:POJ - 3693   题意:给你一个字符串,求重复次数最多的连续重复子串,如果有一样的,取字典序小的字符串. 题解: 比较容易理解的部分就是枚举长度为L,然后看长度为L的字符串最多连续出现 ...

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

    找重复次数最多的字串,如果有多解,要求字典序最小. 我也是跟着罗穗骞菊苣的论文才刷这道题的. 首先还是枚举一个循环节的长度L,如果它出现两次的话,一定会包含s[0], s[L], s[2L]这些相邻两 ...

  4. 【HDOJ】2459 Maximum repetition substring

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

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

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

  6. 【POJ 3693】Maximum repetition substring 重复次数最多的连续重复子串

    后缀数组的论文里的例题,论文里的题解并没有看懂,,, 求一个重复次数最多的连续重复子串,又因为要找最靠前的,所以扫的时候记录最大的重复次数为$ans$,扫完后再后从头暴力扫到尾找重复次数为$ans$的 ...

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

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

  8. poj 3693 Maximum repetition substring (后缀数组)

    其实是论文题.. 题意:求一个字符串中,能由单位串repeat得到的子串中,单位串重复次数最多的子串.若有多个重复次数相同的,输出字典序最小的那个. 解题思路:其实跟论文差不多,我看了很久没看懂,后来 ...

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

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

随机推荐

  1. Oracle使用——Linux系统下使用命令实现oracle数据库数据导入

    背景 在工作当中,数据库的备份及数据导入是必不可少的操作,在完全无界面的Linux操作系统中,我们应该怎样实现oracle数据库的导入呢 前提 服务器已配置ftp 模拟环境 一台linux应用服务器上 ...

  2. ODAC(V9.5.15) 学习笔记(四)TOraDataSet

    名称 类型 说明 SequenceMode TSequenceMode ODAC可以直接利用Oracle中的序列对象为表的主键赋值,从而实现主键自动增长的功能.该属性决定了在什么场合下使用序列: sm ...

  3. Python3 tkinter基础 Checkbutton anchor for生成多个控件并西对齐

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  4. 【做题】CF177G2. Fibonacci Strings——思维+数列

    题意:定义斐波那契字符串为: $f_1 = $ "a" \(f_2 =\) "b" \(f_n = f_{n-1} + f_{n-2}, \, n > 2 ...

  5. 【问题解决】连接mysql 8错误:authentication plugin 'caching_sha2_password

    在刚安装好mysql8,使用native连接的时候报错 authentication plugin 'caching_sha2_password'... 首先确保服务已开启,然后通过cmd命令进入my ...

  6. 【第四十章】Spring Boot 自定义拦截器

    1.首先编写拦截器代码 package com.sarnath.interceptor; import javax.servlet.http.HttpServletRequest; import ja ...

  7. python 之 条件语句

    python 编程语言指定任何非0和非空(null)值为true, 0或者null为false. python 编程中if语句用于控制程序的执行,基本形式为: if 判断条件: 执行语句…… else ...

  8. P4720 【模板】扩展卢卡斯

    思路 扩展Lucas和Lucas定理其实没什么关系 我们要求的是这样的一个问题 \[ \left(\begin{matrix}n\\m\end{matrix}\right) mod\ P \] p不一 ...

  9. (转) GAN论文整理

    本文转自:http://www.jianshu.com/p/2acb804dd811 GAN论文整理 作者 FinlayLiu 已关注 2016.11.09 13:21 字数 1551 阅读 1263 ...

  10. C#Winform工具箱简介

    BindingSource:指定支持事务处理初始化Button:[按钮]用户单击它时引发事件 CheckBox:[复选框]允许用户选择或清除关联选项 CheckedListBox:[复选列表框]显示一 ...