poj3693

题意

给出一个串,求重复次数最多的连续重复子串,输出字典序最小的。

分析

论文 例8(P21)。

Sparse-Table算法预处理出任意两个后缀串的LCP。

code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;
typedef unsigned long long ull;
const int MAXN = 2e5 + 10;
char s[MAXN];
int sa[MAXN], t[MAXN], t2[MAXN], c[MAXN], n; // n 为 字符串长度 + 1,最后一位为数字 0
int rnk[MAXN], height[MAXN];
// 构造字符串 s 的后缀数组。每个字符值必须为 0 ~ m-1
void build_sa(int m) {
int i, *x = t, *y = t2;
for(i = 0; i < m; i++) c[i] = 0;
for(i = 0; i < n; i++) c[x[i] = s[i]]++;
for(i = 1; i < m; i++) c[i] += c[i - 1];
for(i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;
for(int k = 1; k <= n; k <<= 1) {
int p = 0;
for(i = n - k; i < n; i++) y[p++] = i;
for(i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
for(i = 0; i < m; i++) c[i] = 0;
for(i = 0; i < n; i++) c[x[y[i]]]++;
for(i = 0; i < m; i++) c[i] += c[i - 1];
for(i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
swap(x, y);
p = 1; x[sa[0]] = 0;
for(i = 1; i < n; i++)
x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;
if(p >= n) break;
m = p;
}
}
void getHeight() {
int i, j, k = 0;
for(i = 0; i < n; i++) rnk[sa[i]] = i;
for(i = 0; i < n - 1; i++) {
if(k) k--;
j = sa[rnk[i] - 1];
while(s[i + k] == s[j + k]) k++;
height[rnk[i]] = k;
}
}
int dp[MAXN][30];
void init() {
for(int i = 0; i < n; i++) {
dp[i][0] = height[i];
}
for(int i = 1; (1 << i) < MAXN; i++) {
for(int j = 0; j < n; j++) {
dp[j][i] = min(dp[j][i - 1], dp[j + (1 << (i - 1))][i - 1]);
}
}
}
int query(int l, int r) {
if(l > r) swap(l, r);
l++;
int k = (int)(log((double)r - l + 1) / log(2.0));
return min(dp[l][k], dp[r - (1 << k) + 1][k]);
}
int a[MAXN];
int main() {
int Case = 1;
while(~scanf("%s", s) && s[0] != '#') {
int L = strlen(s);
n = L + 1;
build_sa(128);
getHeight();
init();
int mx = 0;
int cnt = 0;
// 寻找重复次数最多的连续子串单个子串的长度,可能有多种重复次数相同的子串
for(int l = 1; l <= L; l++) {
for(int j = 0; j + l < L; j += l) {
int k = query(rnk[j], rnk[j + l]); // lcp
int res = k / l + 1;
int pos = j - (l - (k % l));
if(pos >= 0 && k % l && query(rnk[pos], rnk[pos + l])) res++;
if(res > mx) {
mx = res;
cnt = 0;
a[cnt++] = l;
} else if(res == mx) {
a[cnt++] = l;
}
}
}
// 找字典序最小
int len = 0, st;
for(int i = 1; i < n && !len; i++) {
for(int j = 0; j < cnt; j++) {
if(query(i, rnk[sa[i] + a[j]]) >= (mx - 1) * a[j]) {
len = a[j];
st = sa[i];
break;
}
}
}
printf("Case %d: ", Case++);
for(int i = st; i < st + len * mx; i++) {
printf("%c", s[i]);
}
printf("\n");
}
return 0;
}

poj3693(后缀数组)的更多相关文章

  1. poj3693(后缀数组)

    http://poj.org/problem?id=3693 题意:给出一串字符,需要求这串字符中的最长重复子串,要是有多个,输出字典序最小的......... 我自己的一些想法:这个思路我一开始倒是 ...

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

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

  3. 【poj3693】Maximum repetition substring(后缀数组+RMQ)

    题意:给定一个字符串,求重复次数最多的连续重复子串. 传说中的后缀数组神题,蒟蒻真的调了很久才对啊.感觉对后缀数组和RMQ的模版都不是很熟,导致还是会有很多各种各样的小错误= = 首先,枚举重复子串的 ...

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

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

  5. POJ3693 Maximum repetition substring 后缀数组

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

  6. 关于后缀数组的倍增算法和height数组

    自己看着大牛的论文学了一下后缀数组,看了好久好久,想了好久好久才懂了一点点皮毛TAT 然后就去刷传说中的后缀数组神题,poj3693是进化版的,需要那个相同情况下字典序最小,搞这个搞了超久的说. 先简 ...

  7. 【UVA10829】 L-Gap Substrings (后缀数组)

    Description If a string is in the form UVU, where U is not empty, and V has exactly L characters, we ...

  8. 【uva10829-求形如UVU的串的个数】后缀数组+rmq or 直接for水过

    题意:UVU形式的串的个数,V的长度规定,U要一样,位置不同即为不同字串 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&am ...

  9. 【距离GDOI:131天】 后缀数组完毕

    用了近两周的时间,终于把罗神那篇后缀数组应用看完了,题目也写了一遍,T了无数次...详见前几篇博文... 后缀数组很重要的是那个height数组,可以用来做各种奇奇怪怪的东西...常用方法去是去二分, ...

随机推荐

  1. php导出数据为CSV文件DEMO

    代码示例: private function _download_send_headers($filename) { // disable caching $now = gmdate("D, ...

  2. 【转载】Unity3D研究院之静态自动检查代码缺陷与隐患

    代码缺陷和代码错误的最大区别是,代码缺陷不影响游戏编译,而代码错误编译都不通过.但是代码缺陷会影响游戏发布后产生的一系列BUG..我今天无意间逛外国论坛发现的一个方法,使用了一下感觉挺给力的第一时间分 ...

  3. Abstract Factory 抽象工厂(创建型模式)

    1.常规的对象创建方法(以更换QQ空间主题为例) (这里的常规对象指的是由于业务需求,当前实例化的对象有可能被其他相似的对象(有着共同的特性)所取代,例如更换手机铃声:一首歌取代另一首歌(词,曲,和声 ...

  4. (原)Unreal 渲染模块引言Temp

            @author:白袍小道     引言 本文只在对Unreal渲染模块做一些详细的理解,务求能分析出个大概. 其中框架的思想和实现的过程,是非常值得学习和推敲一二的. 涉及资源系统,材 ...

  5. centos6系列问题

    一.NetworkManager启动问题 1.由于以后要支持e1000版虚拟化网卡,所有centos6镜像均按照NetworkManager服务,并设置开机自启动 2.虚机启动时,默认是Network ...

  6. inspect流程

    当node节点state为manage时,可执行inspector ironic node-set-provision-state <node_uuid> manage ironic no ...

  7. Leetcode 659.分割数组为连续子序列

    分割数组为连续子序列 输入一个按升序排序的整数数组(可能包含重复数字),你需要将它们分割成几个子序列,其中每个子序列至少包含三个连续整数.返回你是否能做出这样的分割? 示例 1: 输入: [1,2,3 ...

  8. 以太访solidity常用的函数有哪些

    以太坊:什么是ERC20标准? 不以规矩,不能成方圆 许多人应该都听过 代码即法律(Code Is Law),因为程序写完了,无论执行多少次都会得到同样的结果,除非有外界因素的干扰.在多人协作的过程中 ...

  9. shell之进程

    ps     System V 风格  -         -elF         -ef         -eF     BSD            a所有跟终端有关的进程           ...

  10. C++ 虚函数的内存分配

    1.无继承的普通类:   在有虚函数的情况下类会为其增加一个隐藏的成员,虚函数表指针,指向一个虚函数表,虚函数表里面就是类的各个虚函数的地址了.那么,虚函数表指针是以什么模型加入到类里面的,虚函数表里 ...