poj3693(后缀数组)
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(后缀数组)的更多相关文章
- poj3693(后缀数组)
http://poj.org/problem?id=3693 题意:给出一串字符,需要求这串字符中的最长重复子串,要是有多个,输出字典序最小的......... 我自己的一些想法:这个思路我一开始倒是 ...
- Maximum repetition substring (poj3693 后缀数组求重复次数最多的连续重复子串)
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6328 Acc ...
- 【poj3693】Maximum repetition substring(后缀数组+RMQ)
题意:给定一个字符串,求重复次数最多的连续重复子串. 传说中的后缀数组神题,蒟蒻真的调了很久才对啊.感觉对后缀数组和RMQ的模版都不是很熟,导致还是会有很多各种各样的小错误= = 首先,枚举重复子串的 ...
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- POJ3693 Maximum repetition substring 后缀数组
POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...
- 关于后缀数组的倍增算法和height数组
自己看着大牛的论文学了一下后缀数组,看了好久好久,想了好久好久才懂了一点点皮毛TAT 然后就去刷传说中的后缀数组神题,poj3693是进化版的,需要那个相同情况下字典序最小,搞这个搞了超久的说. 先简 ...
- 【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 ...
- 【uva10829-求形如UVU的串的个数】后缀数组+rmq or 直接for水过
题意:UVU形式的串的个数,V的长度规定,U要一样,位置不同即为不同字串 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&am ...
- 【距离GDOI:131天】 后缀数组完毕
用了近两周的时间,终于把罗神那篇后缀数组应用看完了,题目也写了一遍,T了无数次...详见前几篇博文... 后缀数组很重要的是那个height数组,可以用来做各种奇奇怪怪的东西...常用方法去是去二分, ...
随机推荐
- WPF and Silverlight.ComboBox 如何通过 Binding IsDropDownOpen 实现下拉菜单展开
In the WPF example the Popup and the ToggleButton (the arrow on the right) are bound with the proper ...
- 【Matrix Factorization】林轩田机器学习技法
在NNet这个系列中讲了Matrix Factorization感觉上怪怪的,但是听完第一小节课程就明白了. 林首先介绍了机器学习里面比较困难的一种问题:categorical features 这种 ...
- 【Lowest Common Ancestor of a Binary Search Tree】cpp
题目: Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in th ...
- ASP NET Core ---Automapper
官方文档:http://docs.automapper.org/en/stable/index.html 一.安装和配置: 二.使用: 1.建立 Profile文件: public class Map ...
- hp raid配置
http://www.cnblogs.com/zhangxinglong/p/5585139.html [root@192e168e100e27 ~]# fdisk -l Disk /dev/nvme ...
- 像Excel的表格table
推荐:Spread.js 地址:点击打开链接 Demo:点击打开链接
- perf 的事件
perf的事件包括: 硬件事件:branch-instrctions / branch-miss / bus-cycles / cache-miss / cache-reference / cycle ...
- 从 C10K 到 C500K
国外的 Urban Airship 公司的工程师在其官方网志上发文章介绍他们在产品环境中做到 50 万并发客户端,Java + Pure NIO 的实现,最近又有文章介绍针对 Linux Kernel ...
- 【bzoj4822/bzoj1935】[Cqoi2017]老C的任务/[Shoi2007]Tree 园丁的烦恼 树状数组
原文地址:http://www.cnblogs.com/GXZlegend/p/6825530.html bzoj4822 题目描述 老 C 是个程序员. 最近老 C 从老板那里接到了一个任务 ...
- 【距离GDOI:131天】 后缀数组完毕
用了近两周的时间,终于把罗神那篇后缀数组应用看完了,题目也写了一遍,T了无数次...详见前几篇博文... 后缀数组很重要的是那个height数组,可以用来做各种奇奇怪怪的东西...常用方法去是去二分, ...