哇哦~想不到我有生之年竟然能够做出字符串的题目ヾ(✿゚▽゚)ノ虽然这题比较裸但依然灰常开心!

  首先有一个棒棒的性质:本质不同的回文串最多有 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回文串的更多相关文章

  1. HDU5421 Victor and String 和 APIO2014 回文串

    两道差不多的题,都是回文自动机right集合处理相关. Victor and String Victor loves to play with string. He thinks a string i ...

  2. BZOJ 3676: [Apio2014]回文串

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2013  Solved: 863[Submit][Status ...

  3. bzoj 3676: [Apio2014]回文串 回文自动机

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 844  Solved: 331[Submit][Status] ...

  4. [模板] 回文树/回文自动机 && BZOJ3676:[Apio2014]回文串

    回文树/回文自动机 放链接: 回文树或者回文自动机,及相关例题 - F.W.Nietzsche - 博客园 状态数的线性证明 并没有看懂上面的证明,所以自己脑补了一个... 引理: 每一个回文串都是字 ...

  5. 【BZOJ 3676】 3676: [Apio2014]回文串 (SAM+Manacher+倍增)

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2343  Solved: 1031 Description 考 ...

  6. [BZOJ3676][APIO2014]回文串(Manacher+SAM)

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 3097  Solved: 1408[Submit][Statu ...

  7. 3676: [Apio2014]回文串

    3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MB Submit: 1740 Solved: 744 [Submit][Status ...

  8. [Bzoj3676][Apio2014]回文串(后缀自动机)(parent树)(倍增)

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 3396  Solved: 1568[Submit][Statu ...

  9. 【bzoj3676】[Apio2014]回文串 —— 回文自动机的学习

    写题遇上一棘手的题,[Apio2014]回文串,一眼看过后缀数组+Manacher.然后就码码码...过是过了,然后看一下[Status],怎么慢这么多,不服..然后就搜了一下,发现一种新东西——回文 ...

  10. bzoj3676 [Apio2014]回文串 卡常+SAM+树上倍增

    bzoj3676 [Apio2014]回文串 SAM+树上倍增 链接 bzoj luogu 思路 根据manacher可以知道,每次暴力扩展才有可能出现新的回文串. 所以推出本质不同的回文串个数是O( ...

随机推荐

  1. HTML基本代码教学,第二天

    HTML 咱们今天来看一下咱们这HTML能做些什么,例如下图(最低级的小实验) 咱们来看一下图片的最左上角<head> <title></ title></ ...

  2. POJ 2251 Dungeon Master (三维BFS)

    题目链接:http://poj.org/problem?id=2251 Dungeon Master Time Limit: 1000MS   Memory Limit: 65536K Total S ...

  3. springmvc传参---LocalDateTime、Date等时间类型转换

    此处定义的dateConvert用来转换Date类型,如果是LocalDate.LocalDateTime类型,则将Date类型换成相应的类型即可,注意java8的日期类型需要用Formatter格式 ...

  4. 自动化运维工具saltstack02 -- 之SaltStack的配置管理

    SaltStack的配置管理 1.配置管理说明 配置管理,顾名思义及配置与管理, salt-master的配置文件编写格式之YAML语法说明: 数据的结构通过缩进来表示,每一级用两个空格来表示缩进,如 ...

  5. 微信 msg_sec_check接口PHP 调用

    $checkContent = '要检测的内容'; $url = 'https://api.weixin.qq.com/wxa/msg_sec_check?access_token='. $res[& ...

  6. MAC终端安装指定版本node

    MAC终端安装指定版本node 安装brew 终端上运行 $ /usr/bin/ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Home ...

  7. 422. Length of Last Word【LintCode java】

    Description Given a string s consists of upper/lower-case alphabets and empty space characters ' ', ...

  8. Matlab中 .' 的作用。

    Syntax B = A.' B = transpose(A)   Description B = A.' returns the nonconjugate transpose of A, that ...

  9. Divide by three, multiply by two(DFS+思维)

    Polycarp likes to play with numbers. He takes some integer number x, writes it down on the board, an ...

  10. lintocde-247-线段树的查询 II

    247-线段树的查询 II 对于一个数组,我们可以对其建立一棵 线段树, 每个结点存储一个额外的值 count 来代表这个结点所指代的数组区间内的元素个数. (数组中并不一定每个位置上都有元素) 实现 ...