Hackerrank--String Function Calculation(后缀数组)
Jane loves string more than anything. She made a function related to the string some days ago and forgot about it. She is now confused about calculating the value of this function. She has a string T with her, and value of string S over function f can be calculated as given below:
f(S)=|S|∗NumberoftimesSoccuringinTJane wants to know the maximum value of f(S) among all the substrings (S) of string T. Can you help her?
Input Format
A single line containing string T in small letter('a' - 'z').Output Format
An integer containing the value of output.Constraints
1 ≤|T|≤ 105Sample Input #00
aaaaaa
Sample Output #00
12
Explanation #00
f('a') = 6
f('aa') = 10
f('aaa') = 12
f('aaaa') = 12
f('aaaaa') = 10
f('aaaaaa') = 6
Sample Input #01
abcabcddd
Sample Output #01
9
Explanation #01
f("a") = 2
f("b") = 2
f("c") = 2
f("ab") = 4
f("bc") = 4
f("ddd") = 3
f("abc") = 6
f("abcabcddd") = 9
Among the function values 9 is the maximum one.
题意:求字符串所有子串中,f(s)的最大值。这里s是某个子串,f(s) = s的长度与s在原字符串中出现次数的乘积。
求得lcp, 转化为求以lcp为高的最大子矩形。
Accepted Code:
#include <string>
#include <iostream>
#include <algorithm>
using namespace std; const int MAX_N = ;
int sa[MAX_N], rk[MAX_N], lcp[MAX_N], tmp[MAX_N], n, k; bool compare_sa(int i, int j) {
if (rk[i] != rk[j]) return rk[i] < rk[j];
int ri = i + k <= n ? rk[i + k] : -;
int rj = j + k <= n ? rk[j + k] : -;
return ri < rj;
} void construct_sa(const string &S, int *sa) {
n = S.length();
for (int i = ; i <= n; i++) {
sa[i] = i;
rk[i] = i < n ? S[i] : -;
} for (k = ; k <= n; k *= ) {
sort(sa, sa + n + , compare_sa); tmp[sa[]] = ;
for (int i = ; i <= n; i++) {
tmp[sa[i]] = tmp[sa[i - ]] + (compare_sa(sa[i - ], sa[i]) ? : );
}
for (int i = ; i <= n; i++) rk[i] = tmp[i];
}
} void construct_lcp(const string &S, int *sa, int *lcp) {
n = S.length();
for (int i = ; i <= n; i++) rk[sa[i]] = i; int h = ;
lcp[] = ;
for (int i = ; i < n; i++) {
int j = sa[rk[i] - ]; if (h > ) h--;
for (; i + h < n && j + h < n; h++) if (S[i + h] != S[j + h]) break; lcp[rk[i] - ] = h;
}
} string S;
int lft[MAX_N], rgt[MAX_N], st[MAX_N], top;
void solve() {
construct_sa(S, sa);
construct_lcp(S, sa, lcp); lcp[n] = n - sa[n];
// for (int i = 1; i <= n; i++) cerr << lcp[i] << ' ';
// cerr << endl;
top = ;
for (int i = ; i <= n; i++) {
while (top && lcp[st[top-]] >= lcp[i]) top--;
if (top) lft[i] = st[top - ] + ;
else lft[i] = ;
st[top++] = i;
}
top = ;
for (int i = n; i > ; i--) {
while (top && lcp[st[top-]] >= lcp[i]) top--;
// attention: rgt[i] should be asigned to st[top - 1]
// rather than st[top - 1] - 1 because lcp[i] is the
// length of the longest common prefix of sa[i] and sa[i + 1].
if (top) rgt[i] = st[top - ];
else rgt[i] = n;
st[top++] = i;
}
long long ans = n;
for (int i = ; i <= n; i++) ans = max(ans, (long long)lcp[i] * (rgt[i] - lft[i] + ));
cout << ans << endl;
} int main(void) {
//ios::sync_with_std(false);
while (cin >> S) solve();
return ;
}
Hackerrank--String Function Calculation(后缀数组)的更多相关文章
- HDU5008 Boring String Problem(后缀数组 + 二分 + 线段树)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5008 Description In this problem, you are given ...
- HDU5853 Jong Hyok and String(二分 + 后缀数组)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5853 Description Jong Hyok loves strings. One da ...
- CF1063F. String Journey(后缀数组+线段树)
题目链接 https://codeforces.com/contest/1063/problem/F 题解 虽然本题有时间复杂度较高但非常好写的做法...... 首先,若答案为 \(k\),则一定存在 ...
- Codeforces 1063F - String Journey(后缀数组+线段树+dp)
Codeforces 题面传送门 & 洛谷题面传送门 神仙题,做了我整整 2.5h,写篇题解纪念下逝去的中午 后排膜拜 1 年前就独立切掉此题的 ymx,我在 2021 年的第 5270 个小 ...
- acdream1116 Gao the string!(hash二分 or 后缀数组)
问题套了一个斐波那契数,归根结底就是要求对于所有后缀s[i...n-1],所有前缀在其中出现的总次数.我一开始做的时候想了好久,后来看了别人的解法才恍然大悟.对于一个后缀来说 s[i...n-1]来说 ...
- 【HDU 5030】Rabbit's String (二分+后缀数组)
Rabbit's String Problem Description Long long ago, there lived a lot of rabbits in the forest. One d ...
- hdu 3553 Just a String (后缀数组)
hdu 3553 Just a String (后缀数组) 题意:很简单,问一个字符串的第k大的子串是谁. 解题思路:后缀数组.先预处理一遍,把能算的都算出来.将后缀按sa排序,假如我们知道答案在那个 ...
- hdu 6194 沈阳网络赛--string string string(后缀数组)
题目链接 Problem Description Uncle Mao is a wonderful ACMER. One day he met an easy problem, but Uncle M ...
- HDU 6194 string string string (后缀数组)
题意:给定一个字符串,问你它有多少个子串恰好出现 k 次. 析:后缀数组,先把height 数组处理出来,然后每次取 k 个进行分析,假设取的是 i ~ i+k-1,那么就有重复的,一个是 i-1 ~ ...
随机推荐
- Qt连接sql server数据库遇到的问题
在QT中使用addDataBase添加一个数据库连接,其中第一个参数应该填入使用数据库驱动的类型,如QMYSQL.QSQLLITE.QSQLPSSQL等. QSqlDatabase QSqlD ...
- P1082 同余方程(扩欧模板)
https://www.luogu.org/problem/P1082 #include <iostream> #include <cstdio> #include <q ...
- [JZOJ5977] 【清华2019冬令营模拟12.15】堆
题目 其中n,q≤500000n,q\leq 500000n,q≤500000 题目大意 让你维护一个堆.支持一下操作: 在某个点的下面加上另一个点,然后进行上浮操作. 询问某一点的权值. 思考历程 ...
- XJOI夏令营501训练1——分配工作
传送门:QAQQAQ 题意:某公司有工作人员x1,x2,…,xn ,他们去做工作y1,y2,…,ym(n<=m) ,每个人都能做其中的几项工作,并且对每一项工作都有一个固定的效率.问能否找到一种 ...
- Sql Server 2005主机和镜像切换SQL语句
--1.主备互换 --主机执行: USE master; ALTER DATABASE <DatabaseName> SET PARTNER FAILOVER; --2.主服务器Down掉 ...
- Ubuntu 16.04下apt安装ssh及卸载(含FileZilla 使用过程)
前言:文件发布测试过程中需要使用Windows和Ubuntu实现文件共享. 以下内容转载自:http://blog.csdn.net/jiang13479/article/details/535014 ...
- vue 关闭微信浏览器(返回路由为undefined时)
参考:https://blog.csdn.net/KingJin_CSDN_/article/details/77050569 main.js: import router from './route ...
- 2019-5-24-WPF-源代码-从零开始写一个-UI-框架
title author date CreateTime categories WPF 源代码 从零开始写一个 UI 框架 lindexi 2019-05-24 15:54:36 +0800 2018 ...
- 嘴巴题8 BZOJ2318: Spoj4060 game with probability Problem
Time Limit: 1 Sec Memory Limit: 128 MB Submit: 555 Solved: 273 [Submit][Status][Discuss] Description ...
- Leetcode139. Word Break单词拆分
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词. 说明: 拆分时可以重复使用字典中的单词. 你可以假设字典中没有重复 ...