博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 3676: [Apio2014]回文串
阅读量:5057 次
发布时间:2019-06-12

本文共 2564 字,大约阅读时间需要 8 分钟。

3676: [Apio2014]回文串

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 2013  Solved: 863
[][][]

Description

考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出 

现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最 
大出现值。 

Input

输入只有一行,为一个只包含小写字母(a -z)的非空字符串s。 

Output

输出一个整数,为逝查回文子串的最大出现值。 

Sample Input

【样例输入l】
abacaba
【样例输入2]
www

Sample Output

【样例输出l】
7
【样例输出2]
4

HINT

 

一个串是回文的,当且仅当它从左到右读和从右到左读完全一样。 
在第一个样例中,回文子串有7个:a,b,c,aba,aca,bacab,abacaba,其中: 
● a出现4次,其出现值为4:1:1=4 
● b出现2次,其出现值为2:1:1=2 
● c出现1次,其出现值为l:1:l=l 
● aba出现2次,其出现值为2:1:3=6 
● aca出现1次,其出现值为1=1:3=3 
●bacab出现1次,其出现值为1:1:5=5 
● abacaba出现1次,其出现值为1:1:7=7 
故最大回文子串出现值为7。 
【数据规模与评分】 
数据满足1≤字符串长度≤300000。

 

Source

 
[ ][ ][ ]

 

 

去自学了一下回文自动机(回文树?),赶脚贼牛逼 ( ఠൠఠ )ノ。然后,就真的是裸题了,23333.

 

当然,如果不用回文自动机也是可以做的。首先用Manacher求出来所有本质不同的回文子串,然后只需要知道每个在原串中出现的次数即可。方法有二,要么后缀数组,要么后缀自动机。后缀自动机的话好像需要倍增,添个$log$不是什么问题?后缀数组的话也需要二分+ST表,还是要添个$log$。

 

1 #include 
2 3 namespace Pal 4 { 5 const int siz = 1000005; 6 int next[siz][26]; 7 int fail[siz]; 8 int cnt[siz]; 9 int len[siz];10 int str[siz];11 int last;12 int tot;13 int n;14 15 inline int node(int l)16 {17 len[tot] = l;18 return tot++;19 }20 21 inline void init(void)22 {23 node(0);24 node(-1);25 last = 0;26 str[0] = -1;27 fail[0] = 1;28 }29 30 inline int getFail(int t)31 {32 while (str[n - len[t] - 1] != str[n])33 t = fail[t];34 return t;35 }36 37 inline void insert(int c)38 {39 str[++n] = c;40 int cur = getFail(last), now;41 if (!next[cur][c])42 {43 now = node(len[cur] + 2);44 fail[now] = next[getFail(fail[cur])][c];45 next[cur][c] = now;46 }47 ++cnt[last = next[cur][c]];48 }49 50 inline void count(void)51 {52 for (int i = tot - 1; ~i; --i)53 cnt[fail[i]] += cnt[i];54 }55 56 inline long long answer(void)57 {58 long long ret = 0;59 60 for (int i = tot - 1; i > 1; --i)61 if (ret < (long long)len[i] * cnt[i])62 ret = (long long)len[i] * cnt[i];63 64 return ret;65 }66 }67 68 const int siz = 300005;69 70 char s[siz];71 72 signed main(void)73 {74 scanf("%s", s);75 76 Pal::init();77 78 for (char *t = s; *t; ++t)79 Pal::insert(*t - 'a');80 81 Pal::count();82 83 printf("%lld\n", Pal::answer());84 }

 

@Author: YouSiki

 

转载于:https://www.cnblogs.com/yousiki/p/6259681.html

你可能感兴趣的文章
hdu 6113 度度熊的01世界(结构体的赋值问题)
查看>>
数据结构学习笔记06排序 (冒泡、插入、希尔、堆排序、归并排序)
查看>>
ionic3 npm install cordova error syscall rename
查看>>
XML的DOM解析 Java实现 使用递归解析一个XML文档
查看>>
java DOM解析XML
查看>>
《JAVA NIO》第一章 简介
查看>>
python OSError: [Errno 22] Invalid argument: '\u202aF://text
查看>>
Programe_Of_Beauty:3.8 求二叉树中节点的最大距离
查看>>
Appium+python断言的使用
查看>>
码农干货系列【3】--割绳子(cut the rope)制作点滴:旋转(rotation)
查看>>
斜率DP题目
查看>>
android:scaleType属性
查看>>
编译.so .a的结果
查看>>
疯狂java学习笔记之面向对象(七) - super关键字
查看>>
磁盘阵列
查看>>
leetcode-1-2
查看>>
linux 存取 I/O 内存
查看>>
时间同步
查看>>
通过Relect反射方法创建对象,获得对象的方法,输出对象信息
查看>>
Cognos报表打开参数
查看>>