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. QBASIC教程

    Qbasic 程序设计入门 BASIC(Beginner’s All-purpose Symbolic Instruction Code 的缩写,意为初学者通用符号指令代码)语言是在1964年由美国的 ...

  2. 服务过美国总统竞选的非传统投票UI [解析及DEMO]

    上篇文章和大家介绍了需求情况和难点分析,大家可以看这个链接了解详细    服务过美国总统竞选的非传统投票UI      =================正文开始=================== ...

  3. paramiko类Fabric主机管理

    环境:Linux python3.5 要求:类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/ ...

  4. linux的screen常用命令使用记录

    新建screen screen 或者 screen -S name - name用于指定一个screen的名字,默认系统随机 暂时退出当前screen ctrl + a + d - 同时按住这三个键即 ...

  5. CentOS7 编译安装nodejs,配置环境变量记录

    每次都装,每次都查 阿里云备案了一个域名,续费了好多年,但是没钱买服务器,就挂在github上.今天收到消息:域名解析服务器不在阿里云,要被GG.只能咬牙买了个阿里云乞丐版. 所有服务都装好了,pin ...

  6. 500 OOPS: vsftpd: refusing to run with writable anonymous root

    500 OOPS: vsftpd: refusing to run with writable anonymous root 以下就是解决的三个步骤,其中第一步,是我一直没有搞明白的,也是其中的重点: ...

  7. JavaScript里面的正则以及eval

    1.eval JavaScript中的eval是Python中eval和exec的合集,既可以编译代码也可以获取返回值. eval() EvalError   执行字符串中的JavaScript代码 ...

  8. HDU 4750 Count The Pairs (离线并查集)

    按边从小到大排序. 对于每条边(from, to, dist),如果from和to在同一个集合中,那么这条边无意义,因为之前肯定有比它更小的边连接了from和to. 如果from和to不属于同一个集合 ...

  9. Tomcat 顶层结构

    Tomcat中最顶层的容器叫Server,代表整个服务器,Server中包含至少一个Service,用于具体提供服务. Service主要包含两部分:Connector   和   Container ...

  10. ocrosoft Contest1316 - 信奥编程之路~~~~~第三关 问题 I: 寻找大富翁

    http://acm.ocrosoft.com/problem.php?cid=1316&pid=8 题目描述 浙江杭州某镇共有n个人,请找出该镇上的前m个大富翁. 输入 输入包含多组测试用例 ...