[bzoj3676][Apio2014]回文串——Manacher+后缀自动机+倍增
Brief Description
一个回文串的value定义为这个回文串的长度乘以出现次数。给定一个字符串,求\(value_{max}\)。
Algorithm Design
我们使用Manacher暴力算出所有的回文子串,放在SAM里倍增,大力算贡献就好了。
Code
#include <algorithm>
#include <cstdio>
#define ll long long
#include <cstring>
const int maxn = 600010;
int n;
ll ans;
int p[maxn];
char str[maxn];
struct Suffix_Automaton {
int trans[maxn][26], fa[maxn][20], pos[maxn], len[maxn], size[maxn];
int last, root, sz;
int v[maxn], q[maxn], dep[maxn];
void init() {
sz = 0;
last = root = ++sz;
}
void insert(int x, int id) {
int p = last, np = last = ++sz;
len[np] = len[p] + 1;
pos[id] = np;
size[np] = 1;
for (; !trans[p][x]; p = fa[p][0])
trans[p][x] = np;
if (p == 0)
fa[np][0] = root;
else {
int q = trans[p][x];
if (len[q] == len[p] + 1) {
fa[np][0] = q;
} else {
int nq = ++sz;
for (int i = 0; i < 26; i++)
trans[nq][i] = trans[q][i];
fa[nq][0] = fa[q][0];
len[nq] = len[p] + 1;
fa[q][0] = fa[np][0] = nq;
for (; trans[p][x] == q; p = fa[p][0])
trans[p][x] = nq;
}
}
}
void pre() {
for (int i = 1; i <= sz; i++)
v[len[i]]++;
for (int i = 1; i <= n; i++)
v[i] += v[i - 1];
for (int i = sz; i >= 1; i--)
q[v[len[i]]--] = i;
for (int i = sz; i >= 1; i--) {
int t = q[i];
size[fa[t][0]] += size[t];
}
for (int i = 1; i <= sz; i++) {
int t = q[i];
dep[t] = dep[fa[t][0]] + 1;
for (int j = 1; (1 << j) <= dep[t]; j++)
fa[t][i] = fa[fa[t][i - 1]][i - 1];
}
}
void query(int l, int r) {
int ret = pos[r];
for (int i = 19; i >= 0; i--) {
int t = fa[ret][i];
if (len[t] >= r - l + 1)
ret = t;
}
ans = std::max(ans, (ll)size[ret] * (r - l + 1));
}
} sam;
void manacher() {
int mx = 1, id = 1;
for (int i = n; i; i--)
str[i * 2] = '#', str[i * 2 - 1] = str[i];
n <<= 1;
for (int i = 1; i <= n; i++) {
p[i] = std::min(p[id * 2 - i], mx - i);
while (i - p[i] > 0 && str[i - p[i]] == str[i + p[i]]) {
int al = (i - p[i]) / 2 + 1;
int ar = (i + p[i] + 1) / 2;
// printf("%d %d\n", al, ar);
sam.query(al, ar);
p[i]++;
}
if (i + p[i] > mx)
mx = i + p[i], id = i;
}
}
int main() {
#ifndef ONLINE_JUDGE
// freopen("input", "r", stdin);
#endif
scanf("%s", str + 1);
n = strlen(str + 1);
str[0] = '+', str[n + 1] = '-';
sam.init();
for (int i = 1; i <= n; i++) {
sam.insert(str[i] - 'a', i);
}
sam.pre();
manacher();
printf("%lld\n", ans);
}
[bzoj3676][Apio2014]回文串——Manacher+后缀自动机+倍增的更多相关文章
- [Bzoj3676][Apio2014]回文串(后缀自动机)(parent树)(倍增)
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 3396 Solved: 1568[Submit][Statu ...
- 2018.12.15 bzoj3676: [Apio2014]回文串(后缀自动机)
传送门 对原串建立一个后缀自动机,然后用反串在上面匹配. 如果当前匹配的区间[l,r][l,r][l,r]包裹了当前状态的endposendposendpos中的最大值,那么[l,maxpos][l, ...
- [BZOJ3676][APIO2014]回文串(Manacher+SAM)
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 3097 Solved: 1408[Submit][Statu ...
- BZOJ3676 APIO2014 回文串 Manacher、SA
传送门 首先一个结论:串\(S\)中本质不同的回文串个数最多有\(|S|\)个 证明考虑以点\(i\)结尾的所有回文串,假设为\(S[l_1,i],S[l_2,i],...,S[l_k,i]\),其中 ...
- [APIO2014]回文串 manacher 后缀数组
题面:洛谷 题解: 还是这个性质:对于每个串而言,本质不同的回文串最多只有O(n)个. 所以我们先求出这O(n)个本质不同的回文串,然后对整个串求一次sa. 然后对于每个回文串,求出它的出现次数,更新 ...
- bzoj 3676: [Apio2014]回文串【后缀自动机+manacher】
用manacher找出本质不同的回文子串放在SAM上跑 #include<iostream> #include<cstdio> #include<cstring> ...
- [模板] 回文树/回文自动机 && BZOJ3676:[Apio2014]回文串
回文树/回文自动机 放链接: 回文树或者回文自动机,及相关例题 - F.W.Nietzsche - 博客园 状态数的线性证明 并没有看懂上面的证明,所以自己脑补了一个... 引理: 每一个回文串都是字 ...
- bzoj3676 [Apio2014]回文串 卡常+SAM+树上倍增
bzoj3676 [Apio2014]回文串 SAM+树上倍增 链接 bzoj luogu 思路 根据manacher可以知道,每次暴力扩展才有可能出现新的回文串. 所以推出本质不同的回文串个数是O( ...
- BZOJ3676 APIO2014回文串(manacher+后缀自动机)
由于本质不同的回文子串数量是O(n)的,考虑在对于每个回文子串在第一次找到它时对其暴力统计.可以发现manacher时若右端点移动则找到了一个新回文串.注意这样会漏掉串长为1的情况,特判一下. 现在问 ...
随机推荐
- ArcGIS Server远程处理服务器(环境设置)
当使用ArcGIS Server做远程处理服务器执行影像处理操作时,提示ERROR 999999通用错误代码,如下: Start Time: Mon Jul 03 13:49:06 2017Distr ...
- Java的框架是什么意思
框架就是一些类和接口的集合,通过这些类和接口协调来完成一系列的程序实现. JAVA框架可以分为三层:表示层,业务层和物理层.框架又叫做开发中的半成品,它不能提供整个WEB应用程序的所有东西,但是有了框 ...
- react实现页面切换动画效果
一.前情概要 注:(我使用的路由是react-router4) 如下图所示,我们需要在页面切换时有一个过渡效果,这样就不会使页面切换显得生硬,用户体验大大提升: but the 问题是 ...
- devstack环境搭建
1. devstack部署 参考Quick Start,推荐使用ubuntu16.04进行安装 1.1 配置ubuntu国内源 修改/etc/apt/sources.list内容为 deb http: ...
- 剑指offer-数值的整数次方12
class Solution: def Power(self, base, exponent): # write code here if base==0: return 0 if exponent= ...
- POJ 3858 Hurry Plotter(DP)
Description A plotter is a vector graphics printing device that connects to a computer to print grap ...
- python学习笔记-list的用法
1.list的定义 list = [] list = [1,2,'a','b'](list中的元素不一定是一个类型) 2.list的操作 1)list.append(value) 2)list.ins ...
- Elicpse新建userLibrary导入jar包时抛出NotFoundException异常
最近刚开始学Struts2.0框架.再导入jar包的时候突然心血来潮.为方便区分jar包的功能,于是想在WEB-INF -> lib 目录下想新建一个struts文件夹,以方便分类查看. 像上图 ...
- c# 调用 matlab 引发初始化错误 异常
1. 除了matlab 编译的DLL 意外还需要引用 MWArray.dll 这个dill 在安装了 MCRInstaller.exe(matlab运行环境之后就会有了): 2. 最重要的一点.ne ...
- [剑指Offer] 26.二叉搜索树与双向链表
[思路]因为二叉搜索树的中序遍历就是递增排列的,所以只要在中序遍历时将每个结点放入vector中,再分别为每个结点的左右指针赋值即可. /* struct TreeNode { int val; st ...