【题解】APIO2014回文串
哇哦~想不到我有生之年竟然能够做出字符串的题目ヾ(✿゚▽゚)ノ虽然这题比较裸但依然灰常开心!
首先有一个棒棒的性质:本质不同的回文串最多有 O(n) 个。首先 manacher 把它们都找出来,然后问题就变成了给定 n 个子串,求它们在原串中出现的次数。求出 height 然后二分一下即可(这个好像是SA 的基础操作?)。
#include <bits/stdc++.h>
using namespace std;
#define maxn 601550
#define CNST 22
int n, N, m, p1[maxn], p2[maxn], rk[maxn], bits[CNST];
int p[maxn], rec[maxn], t[maxn], y[maxn], Log[maxn];
int num[maxn], SA[maxn], ST[maxn][CNST];
long long ans;
char a[maxn], s[maxn]; void pre()
{
s[] = s[] = '#'; s[ * n + ] = '?';
for(int i = ; i < n; i ++) s[i * + ] = a[i], s[i * + ] = '#';
N = n * + ;
} void Up(int &x, int y) { x = (x > y) ? x : y; }
void manacher()
{
int mid = , mr = ;
for(int i = ; i < N; i ++)
{
if(i <= mr) p[i] = min(p[(mid << ) - i], p[mid] + mid - i);
else p[i] = ; Up(rec[i + p[i] - ], p[i]);
while(s[i + p[i]] == s[i - p[i]])
{
p[i] ++;
Up(rec[i + p[i] - ], p[i]);
}
if(p[i] + i - > mr) mr = p[i] + i - , mid = i;
}
} //SA
void Rsort(int *p, int *x, int *id)
{
for(int i = ; i <= m; i ++) t[i] = ;
for(int i = ; i <= n; i ++) t[p[i]] ++;
for(int i = ; i <= m; i ++) t[i] += t[i - ];
for(int i = n; i >= ; i --) x[t[p[id[i]]] --] = id[i];
} bool cmp(int x, int y) { return y && (p1[x] == p1[y] && p2[x] == p2[y]); }
void Get_SA()
{
m = ;
for(int k = ; bits[k] <= n; k ++)
{
for(int i = ; i <= n; i ++)
p1[i] = rk[i], p2[i] = (i + bits[k] <= n) ? rk[i + bits[k]] : ;
Rsort(p2, y, num); Rsort(p1, SA, y);
for(int i = , p = ; i <= n; m = p, i ++)
rk[SA[i]] = cmp(SA[i - ], SA[i]) ? p : ++ p;
if(m >= n) break;
}
} void Get_Height()
{
for(int i = , k = ; i <= n; i ++)
{
if(k) k --;
int j = SA[rk[i] - ];
while(max(i, j) + k - <= n && a[j + k - ] == a[i + k - ]) k ++;
ST[rk[i]][] = k;
}
} void Build()
{
for(int j = ; j < CNST; j ++)
for(int i = ; i + bits[j] - <= n; i ++)
ST[i][j] = min(ST[i][j - ], ST[i + bits[j - ]][j - ]);
} int RMQ(int x, int y)
{
if(y < x) swap(x, y);
int k = Log[y - x + ];
return min(ST[x][k], ST[y - bits[k] + ][k]);
} int Query(int x, int len)
{
int l = , r = rk[x], ans2 = rk[x], ans1 = rk[x] + ;
while(l <= r)
{
int mid = (l + r) >> ;
if(RMQ(rk[x], mid) >= len) ans1 = mid, r = mid - ;
else l = mid + ;
} ans1 --; l = rk[x] + , r = n;
while(l <= r)
{
int mid = (l + r) >> ;
if(RMQ(rk[x] + , mid) >= len) ans2 = mid, l = mid + ;
else r = mid - ;
}
return ans2 - ans1 + ;
} void init()
{
Log[] = -; for(int i = ; i < maxn; i ++) Log[i] = Log[i >> ] + ;
bits[] = ; for(int i = ; i < CNST; i ++) bits[i] = bits[i - ] << ;
for(int i = ; i < maxn; i ++) num[i] = i;
} int main()
{
init();
scanf("%s", a); n = strlen(a);
pre(); manacher();
for(int i = ; i <= n; i ++) rk[i] = a[i - ];
Get_SA(); Get_Height(); Build();
for(int i = ; i < N; i ++)
{
if(s[i] == '#') continue;
int r = (i - ) >> ;
int l = r - rec[i] + ; r ++, l ++;
int t = Query(l, r - l + );
ans = max(ans, 1ll * t * (r - l + ));
}
printf("%lld\n", ans);
return ;
}
【题解】APIO2014回文串的更多相关文章
- HDU5421 Victor and String 和 APIO2014 回文串
两道差不多的题,都是回文自动机right集合处理相关. Victor and String Victor loves to play with string. He thinks a string i ...
- BZOJ 3676: [Apio2014]回文串
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2013 Solved: 863[Submit][Status ...
- bzoj 3676: [Apio2014]回文串 回文自动机
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 844 Solved: 331[Submit][Status] ...
- [模板] 回文树/回文自动机 && BZOJ3676:[Apio2014]回文串
回文树/回文自动机 放链接: 回文树或者回文自动机,及相关例题 - F.W.Nietzsche - 博客园 状态数的线性证明 并没有看懂上面的证明,所以自己脑补了一个... 引理: 每一个回文串都是字 ...
- 【BZOJ 3676】 3676: [Apio2014]回文串 (SAM+Manacher+倍增)
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2343 Solved: 1031 Description 考 ...
- [BZOJ3676][APIO2014]回文串(Manacher+SAM)
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 3097 Solved: 1408[Submit][Statu ...
- 3676: [Apio2014]回文串
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MB Submit: 1740 Solved: 744 [Submit][Status ...
- [Bzoj3676][Apio2014]回文串(后缀自动机)(parent树)(倍增)
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 3396 Solved: 1568[Submit][Statu ...
- 【bzoj3676】[Apio2014]回文串 —— 回文自动机的学习
写题遇上一棘手的题,[Apio2014]回文串,一眼看过后缀数组+Manacher.然后就码码码...过是过了,然后看一下[Status],怎么慢这么多,不服..然后就搜了一下,发现一种新东西——回文 ...
- bzoj3676 [Apio2014]回文串 卡常+SAM+树上倍增
bzoj3676 [Apio2014]回文串 SAM+树上倍增 链接 bzoj luogu 思路 根据manacher可以知道,每次暴力扩展才有可能出现新的回文串. 所以推出本质不同的回文串个数是O( ...
随机推荐
- golang 单元测试
单元测试是质量保证十分重要的一环,好的单元测试不仅能及时地发现问题,更能够方便地调试,提高生产效率.所以很多人认为写单元测试是需要额外的时间,会降低生产效率,是对单元测试最大的偏见和误解. go 语言 ...
- 深入解析QML引擎, 第3部分: 绑定类型
原文 QML Engine Internals, Part 3: Binding Types 译者注:这个解析QML引擎的文章共4篇,分析非常透彻,在国内几乎没有找到类似的分析,为了便于国内的QT/Q ...
- 三边定位 c#
MATLAB是美国MathWorks公司出品的商业数学软件,用于算法开发.数据可视化.数据分析以及数值计算的高级技术计算语言和交互式环境,主要包括MATLAB和Simulink两大部分. 项目中用到三 ...
- 区块链技术:每位CEO都应了解
区块链技术有可能成为一项广泛应用的突破性技术,像蒸汽机.电力或因特网那 样,改变整个社会和经济的运行方式. 对企业而言,信任至关重要.今天,我们基于信任,将钱存放在银行,通过电商企业 网购产品,并且依 ...
- smartgit 过期
进入到安装目录把Setting.xml 文件删除然后,再次打开就可以正常使用了.
- cmake-index-3.11.4机翻
index next | CMake » git-stage git-master latest release 3.13 3.12 3.11.4 3.10 3.9 3.8 3.7 3.6 3.5 3 ...
- leetcode个人题解——#31 Next Permutation
写这题时脑子比较混乱,重写了一遍wiki大佬的解法. 算法: According to Wikipedia, a man named Narayana Pandita presented the fo ...
- ASP.NET MVC - 启动创建项目,未能加载错误
VS2012以常规方式创建一ASP.NET MVC internet 项目.创建后F5启动项目,遇一错误: 未能加载文件或程序集“MySql.Web.v20, Version=6.9.4.0, Cul ...
- 实现属于自己的TensorFlow(二) - 梯度计算与反向传播
前言 上一篇中介绍了计算图以及前向传播的实现,本文中将主要介绍对于模型优化非常重要的反向传播算法以及反向传播算法中梯度计算的实现.因为在计算梯度的时候需要涉及到矩阵梯度的计算,本文针对几种常用操作的梯 ...
- Scrum立会报告+燃尽图(十月二十九日总第二十次)
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2288 项目地址:https://git.coding.net/zhang ...