题面:洛谷

题解:

  还是这个性质:对于每个串而言,本质不同的回文串最多只有O(n)个。

  所以我们先求出这O(n)个本质不同的回文串,然后对整个串求一次sa。

  然后对于每个回文串,求出它的出现次数,更新答案即可。

  如何用后缀数组求一个串的出现次数?

  因为每个串都必然是某个后缀的前缀。因此我们先找到这个串x,然后在周围二分,寻找一个最大的区间[l, r]使得区间内每个串与x的LCP都大于等于这个串的长度。

  可以证明,这样的区间必然是连续的一个。

  因此在周围分别向上向下二分一下最多能延伸到哪,是否可行用st表维护一下height数组的最小值即可O(1)查询LCP大小。

  

 // luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 601000
#define ac 601000
#define LL long long int n, m = , pos, maxn;
LL ans;
int r[ac], sa[AC], rk[AC], p1[AC], p2[AC], b[AC], d[AC];//第几是谁,你是第几, 两个关键字,临时数组,桶
int st[AC][], h[AC], last[AC], length[AC];
char ss[AC], s[ac];//原串,扩充串 inline void upmax(LL &a, LL b){
if(b > a) a = b;
} void pre()
{
scanf("%s", ss + ), n = strlen(ss + );
s[] = '$', s[] = '#';
for(R i = ; i <= n; i ++) s[i << ] = ss[i], s[(i << ) + ] = '#';//manacher数组
for(R i = ; i <= n; i ++) sa[i] = i, rk[i] = ss[i];//初始化后缀数组
} void ssort()
{
for(R i = ; i <= n; i ++) ++ d[p2[i]];
for(R i = ; i <= m; i ++) d[i] += d[i - ];
for(R i = ; i <= n; i ++) b[d[p2[i]] --] = i;//给i分配排名(临时sa数组)
for(R i = ; i <= m; i ++) d[i] = ; for(R i = ; i <= n; i ++) ++ d[p1[i]];
for(R i = ; i <= m; i ++) d[i] += d[i - ];
for(R i = n; i; i --) sa[d[p1[b[i]]] --] = b[i];//依次给b[i]分配排名
for(R i = ; i <= m; i ++) d[i] = ;
} void sa_sort()
{
for(R k = ; k <= n; k <<= )
{
for(R i = ; i <= n; i ++)
p1[i] = rk[i], p2[i] = rk[i + k];
ssort();
int tmp = ;
rk[sa[]] = ;
for(R i = ; i <= n; i ++)
rk[sa[i]] = (p1[sa[i]] == p1[sa[i - ]] && p2[sa[i]] == p2[sa[i - ]]) ? tmp : ++ tmp;
if(tmp >= n) break;
m = tmp;
}
} void manacher()//获取回文串
{
int b = * n;
for(R i = ; i <= b; i ++)
{
r[i] = (maxn > i) ? min(r[(pos << ) - i], maxn - i + ) : ;
while(s[i - r[i]] == s[i + r[i]]) ++ r[i];
int t = i + r[i] - ;
if(t > maxn)
{
for(R j = maxn + ; j <= t; ++ j)
{
last[j] = (i << ) - j;//串的开始是要算的,,,,
if(s[j] == '#') continue;
length[j] = ((j - last[j]) >> ) + ;
}
pos = i, maxn = t;
}
} /*for(R i = 1; i <= b; i ++)
{
if(s[i] == '#') continue;
length[i] = ((i - last[i]) >> 1) + 1;//(r - l) / 2 + 1算出字母的长度(个数)
}*/
} void build()//求height数组
{
//h[sa[1]] = 0;
for(R i = , k = ; i <= n; i ++)//按照原串顺序求h
{
if(k) -- k;//将k变为上一次的h[i] - 1
int j = sa[rk[i] - ];
while(ss[i + k] == ss[j + k] && k <= n) ++ k;
h[rk[i]] = k;
}
} int t1[AC], t2[AC];//最接近i的2的n次幂的指数,对应的大小 void get_st()
{
int tt = , tmp = ;
for(R i = ; i <= n; i ++)
{
st[i][] = h[i];
if(i == (tmp << )) tmp <<= , ++ tt;
t1[i] = tt, t2[i] = tmp;
}
tmp = ;
for(R i = ; i <= ; i ++)
{
for(R j = ; j <= n; j ++)
st[j][i] = min(st[j][i - ], st[j + tmp][i - ]);
tmp <<= ;
}
} bool check(int l, int r, int lim)//看min[l, r]是否>= lim
{
int rnt = , len = (r - l + );
rnt = min(st[l][t1[len]], st[r - t2[len] + ][t1[len]]);
return rnt >= lim;
} LL half(int x, int len)//获取出现次数
{
int l = , r = x;
while(l < r)//查找前一段里面第一个符合的
{
int mid = (l + r) >> ;
if(check(mid + , x, len)) r = mid;
else l = mid + ;
}
int ll = l;//记录左边界
l = x, r = n;
while(l < r)//查找后一段里面最后一个符合的
{
int mid = (l + r + ) >> ;
if(check(x + , mid, len)) l = mid;
else r = mid - ;
}
return r - ll + ;
} void work()
{
int b = * n;
for(R i = ; i <= b; i ++)
{
if(s[i] == '#') continue;
upmax(ans, 1LL * length[i] * half(rk[last[i] >> ], length[i]));
}
printf("%lld\n", ans);
} int main()
{
// freopen("in.in", "r", stdin);
pre();
sa_sort();
build();
get_st();
manacher();
work();
// fclose(stdin);
return ;
}

[APIO2014]回文串 manacher 后缀数组的更多相关文章

  1. [bzoj3676][Apio2014]回文串——Manacher+后缀自动机+倍增

    Brief Description 一个回文串的value定义为这个回文串的长度乘以出现次数.给定一个字符串,求\(value_{max}\). Algorithm Design 我们使用Manach ...

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

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

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

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

  4. BZOJ4755 [JSOI2016]扭动的回文串 【后缀数组】【manacher】

    题目分析: 我写了史上最丑的后缀数组,怎么办? 首先manacher一遍两个串,这样只用考虑第三问.用$作为间隔符拼接两个串,把第一个串翻转.枚举回文中心,取最长的回文串,对于剩下的部分利用LCP匹配 ...

  5. BZOJ3676 APIO2014 回文串 Manacher、SA

    传送门 首先一个结论:串\(S\)中本质不同的回文串个数最多有\(|S|\)个 证明考虑以点\(i\)结尾的所有回文串,假设为\(S[l_1,i],S[l_2,i],...,S[l_k,i]\),其中 ...

  6. 2018.12.15 bzoj3676: [Apio2014]回文串(后缀自动机)

    传送门 对原串建立一个后缀自动机,然后用反串在上面匹配. 如果当前匹配的区间[l,r][l,r][l,r]包裹了当前状态的endposendposendpos中的最大值,那么[l,maxpos][l, ...

  7. bzoj 3676: [Apio2014]回文串【后缀自动机+manacher】

    用manacher找出本质不同的回文子串放在SAM上跑 #include<iostream> #include<cstdio> #include<cstring> ...

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

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

  9. BZOJ 3676: [Apio2014]回文串

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

随机推荐

  1. cdh中hdfs非ha环境迁移Namenode与secondaryNamenode,从uc机器到阿里;

    1.停掉外部接入服务: 2 NameNode Metadata备份: 2.1 备份fsimage数据,(该操作适用HA和非HA的NameNode),使用如下命令进行备份: [root@cdh01 df ...

  2. 海思NB-IOT的SDK里面写KV键值对值掉电保存参数

    1. 写函数,ICCID_CTRL_KEY  这个是键,有些是海思已经使用的,所以自己定义的时候要错开,函数的第二个参数是数据指针,第三个参数是数据长度 #define ICCID_CTRL_KEY ...

  3. git remote: error: hook declined to update

    提交一个项目,push的时候,报错: remote: error: File xxx.rar is MB; this exceeds Git@OSC's file size limit of 100 ...

  4. tomcat 部署项目到服务器

    参考博客,我选了一种最简单的方法来部署项目. 在tomcat 目录下 的  conf\Catalina\localhost 目录中,新建一个   ' 项目名.xml '   文件,名字用项目名表示, ...

  5. JavaScript 中函数的参数

    functionName(parameter1, parameter2, parameter3) { // 要执行的代码…… } 参数规则 JavaScript 函数定义时形参没有指定数据类型. Ja ...

  6. Nginx之一:Nginx的编译安装

    一.Nginx简介 官方网址:http://nginx.org/ Nginx是由1994年毕业于俄罗斯国立莫斯科鲍曼科技大学的同学为俄罗斯rambler.ru公司开发的,开发工作最早从2002年开始, ...

  7. 002 -- MySQL的逻辑架构

                                            msql的逻辑架构图 第一层:主要功能是连接处理.授权认证.安全等.相当于JavaEE中的常说的Web层 第二层:包含了 ...

  8. C# ArcFace 免费人脸识别 2.0 demo

    **配置过程:** 1. 到[虹软官网](https://ai.arcsoft.com.cn/index.htm?utm_source=csdn&utm_medium=referral)下载S ...

  9. zabbix监控历史数据清理

    2018/12/24 14:00:57  zabbix监控运行一段时间以后,会留下大量的历史监控数据,zabbix数据库一直在增大:可能会造成系统性能下降,查看历史数据室查询速度缓慢. zabbix里 ...

  10. We are writing to let you know we have removed your selling privileges

     Hello, We are writing to let you know we have removed your selling privileges, canceled your listin ...