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. topcoder srm list

    300 305 310 315 320 325 330 335 340 350 360 370 380 390 400 410 415 420 425 430 435 440 445 450 455 ...

  2. SVM学习笔记5-SMO

    首先拿出最后要求解的问题:$\underset{\alpha}{min}W(\alpha)=\frac{1}{2} \sum_{i,j=1}^{n}y^{(i)}y^{(j)}\alpha_{i}\a ...

  3. Bootstrap3基础 input-group-btn 按钮与输入框 横向组合

      内容 参数   OS   Windows 10 x64   browser   Firefox 65.0.2   framework     Bootstrap 3.3.7   editor    ...

  4. Concepts-->Migrations

    https://flywaydb.org/documentation/migrations Overview With Flyway all changes to the database are c ...

  5. P4450 双亲数

    思路 同zap-queries 莫比乌斯反演的板子 数据范围小到不用整除分块... 代码 #include <cstdio> #include <algorithm> #inc ...

  6. 题解——loj6277 数列分块入门1(分块)

    分块裸题 然后就是记得左右边界处理和分块的初始化 忘了初始化会被卡成暴力 #include <cstdio> #include <algorithm> #include < ...

  7. 【Hadoop 分布式部署 四:配置Hadoop 2.x 中主节点(NN和RM)到从节点的SSH无密码登录】

    *******************                一定要使这三台机器的用户名相同,安装目录相同          ************* SSH 无密钥登录的简单介绍(之前再搭 ...

  8. CentOS7使用httpd apache 和firewalld打开关闭防火墙与端口

    Centos7 使用systemctl 工具操作命令 systemctl 是Centos7的服务管理工具中的主要工具 ,它融合之前service和chkconfig的功能于一体 一.httpd的设置 ...

  9. CSS属性大全

    字体属性:(font)大小 font-size:x-large;(特大) xx-small;(极小) 一般中文用不到,只要用数值就可以,单位:PX.PD样式 font-style:oblique;(偏 ...

  10. git项目,VSCode显示不同颜色块的含义

    一. 概念 代码里的左侧颜色标识: 红色,未加入版本控制; (刚clone到本地) 绿色,已经加入版本控制暂未提交; (新增部分) 蓝色,加入版本控制,已提交,有改动: (修改部分) 白色,加入版本控 ...