【题解】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( ...
随机推荐
- crontab练习题
Crontab练习题 每周一到周六的凌晨3点20分,运行tar命令对/etc/目录进行存档另存,存储位置为/backups/etc-YYYY-MM-DD.tar.gz 20 3 * * 1-6 /us ...
- 16、Java并发编程:Timer和TimerTask
Java并发编程:Timer和TimerTask(转载) 下面内容转载自: http://blog.csdn.net/xieyuooo/article/details/8607220 其实就Timer ...
- 数据结构思维导图 Part1
刚刚结束数据结构的学习,在复习阶段,所以做来思维导图总结一下. 思维导图,顾名思义是应该有对思维有引导作用的,就像思维的整理术,然而想要学好什么,光看思维导图总是不够的. 树与图作为两个复杂非线性结构 ...
- SOAPUI参数中xml中CDATA包含问题
<![CDATA[ <Request> <CardNo>000002629518</CardNo> <SecrityNo/> <BankTr ...
- Unity学习笔记(1)
transform: transform是GameObject的一个默认的组件,其包含着该对象的几种属性,坐标(Position)以及旋转角度(Rotation)和尺寸(Scale). transfo ...
- hdu - 6277,2018CCPC湖南全国邀请赛B题,找规律,贪心找最优.
题意: 给出N个小时,分配这些小时去写若干份论文,若用1小时写一份论文,该论文会被引用A次,新写一篇论文的话,全面的论文会被新论文引用一次. 找最大的H,H是指存在H遍论文,而且这些论文各被引用大于H ...
- 《Cocos2d-x游戏开发实战精解》学习笔记3--在Cocos2d-x中播放声音
<Cocos2d-x游戏开发实战精解>学习笔记1--在Cocos2d中显示图像 <Cocos2d-x游戏开发实战精解>学习笔记2--在Cocos2d-x中显示一行文字 之前的内 ...
- springboot 集成 swagger
1. 首先配置swaggerConfigpackage com.lixcx.lismservice.config; import com.lixcx.lismservice.format.Custom ...
- FPGA的过去,现在和未来
我们知道,相对于专业的ASIC,FPGA有上市时间和成本上的优势.另外,在大多数情况下,FPGA执行某些功能较之CPU上的软件操作更高效.这就是为什么我们认为它不但会运用在数据中心的服务器.交换器.存 ...
- POJ 3784 Running Median(动态维护中位数)
Description For this problem, you will write a program that reads in a sequence of 32-bit signed int ...