思路:用马拉车把一个串中的回文串个数降到O(n)级别,然后每个串在后缀自动机上倍增找个数。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define PLI pair<LL, int>
#define ull unsigned long long
using namespace std; const int N = + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const double eps = 1e-;
const int base = ; int n, m, p[N<<];
char s[N<<]; struct SuffixAutomaton {
int last, cur, cnt, ch[N<<][], id[N<<], fa[N<<], dis[N<<], sz[N<<], c[N];
int f[N<<][], pos[N<<];
SuffixAutomaton() {cur = cnt = ;}
void init() {
for(int i = ; i <= cnt; i++) {
memset(ch[i], , sizeof(ch[i]));
sz[i] = c[i] = dis[i] = fa[i] = ;
}
cur = cnt = ;
}
void extend(int c, int id) {
last = cur; cur = ++cnt;
int p = last; dis[cur] = id;
for(; p && !ch[p][c]; p = fa[p]) ch[p][c] = cur;
if(!p) fa[cur] = ;
else {
int q = ch[p][c];
if(dis[q] == dis[p]+) fa[cur] = q;
else {
int nt = ++cnt; dis[nt] = dis[p]+;
memcpy(ch[nt], ch[q], sizeof(ch[q]));
fa[nt] = fa[q]; fa[q] = fa[cur] = nt;
for(; ch[p][c]==q; p=fa[p]) ch[p][c] = nt;
}
}
sz[cur] = ;
}
void getSize(int n) {
for(int i = ; i <= cnt; i++) c[dis[i]]++;
for(int i = ; i <= n; i++) c[i] += c[i-];
for(int i = cnt; i >= ; i--) id[c[dis[i]]--] = i;
for(int i = cnt; i >= ; i--) {
int p = id[i];
sz[fa[p]] += sz[p];
}
}
LL query(int p, int len) {
for(int j = ; j >= ; j--) {
if(f[p][j] && dis[f[p][j]] >= len) p = f[p][j];
}
return 1ll*len*sz[p];
}
void solve() {
for(int i = , p = ; i <= n; i++)
p = ch[p][s[i]-'a'], pos[i] = p;
for(int i = ; i <= cnt; i++) f[i][] = fa[i];
for(int j = ; j < ; j++)
for(int i = ; i <= cnt; i++)
f[i][j] = f[f[i][j-]][j-]; LL ans = ;
s[] = '-', s[n+] = '+';
int mx = , id = ;
for(int i = ; i <= n; i++) {
if(mx > i) p[i] = min(mx-i, p[*id-i]);
else p[i]=, ans = max(ans, query(pos[i], ));
while(s[i+p[i]]==s[i-p[i]]) p[i]++, ans = max(ans, query(pos[i+p[i]-], *p[i]-));
if(i+p[i]>mx) mx = i+p[i], id = i;
}
mx = , id = ;
for(int i = ; i <= n; i++) {
if(mx > i) p[i] = min(mx-i, p[*id-i]);
else p[i] = ;
while(s[i+p[i]+]==s[i-p[i]]) p[i]++, ans = max(ans, query(pos[i+p[i]], *p[i]));
if(i+p[i]>mx) mx = i+p[i], id = i;
}
printf("%lld\n", ans);
}
} sam; int main() {
scanf("%s", s + );
n = strlen(s + );
for(int i = ; i <= n; i++)
sam.extend(s[i]-'a', i);
sam.getSize(n);
sam.solve();
return ;
} /*
*/

最新文章

  1. [转]libevent简介和使用
  2. 【代码笔记】iOS-3个section,每个都有header.
  3. 《敏捷个人-认识自我、管理自我.pdf》更新至 v0.7
  4. android ImageSwitcher
  5. 51nod1476 括号序列的最小代价
  6. HDU5463 Clarke and minecraft
  7. java中关于static的小知识
  8. 7-ajax的同步和异步?
  9. iOS NSInvocation的学习
  10. windows搭建代理服务器
  11. easygen通用代码生成框架[开源]
  12. 论decltype和auto的区别
  13. JxBrowser之一:Java嵌入Chrome浏览器
  14. Win7关机时弹出对话框,提示你想要的信息
  15. 133个Java面试问题列表
  16. 如何判断单链表是否存在环 &amp; 判断两链表是否相交
  17. 阿里云ftp连接遇到的错误,entering passive mode失败(一个并不成熟的产品?)
  18. VB6.0中数组的定义实測
  19. [Vue warn]: Missing required prop: &quot;title&quot;
  20. Nginx 教程示例

热门文章

  1. bzoj千题计划126:bzoj1038: [ZJOI2008]瞭望塔
  2. Intellij IDEA设置及快捷键使用总结
  3. 《Science》:对年轻科学家的忠告
  4. [转载]WebStorm快捷键操作
  5. 【转】C#使用PrintDocument打印 多页 打印预览
  6. CodeForces 816C 思维
  7. AAC编码
  8. js中call与apply的区别以及使用~
  9. JSON数据填充表格——(三)
  10. Strusts2笔记7--国际化