[bzoj2342][Shoi2011]双倍回文 manacher

来源:互联网 发布:网络流行尴舞视频 编辑:程序博客网 时间:2024/06/12 22:05

2342: [Shoi2011]双倍回文

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 2734  Solved: 1051
[Submit][Status][Discuss]

Description

Input

输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容。

Output

输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文子串不存在,则输出0

Sample Input

16
ggabaabaabaaball

Sample Output

12

HINT

N<=500000

Source

蒟蒻表示第一次写manacher都写不来
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<set>using namespace std;const int N = 500000 + 5;int n,ans,q[N],p[N];char ch[N];set<int> t;bool cmp( int a, int b ){return (a-p[a]) < (b-p[b]);}void manacher(){int mx = 0, id;for( int i = 1; i <= n; i++ ){if( mx > i ) p[i] = min(mx-i,p[2*id-i]);else p[i] = 0;for( ; ch[i-p[i]] == ch[i+p[i]+1] ; p[i]++ );if( p[i] + i > mx ) id = i, mx = p[i] + i;}}int main(){scanf("%d%s", &n, ch+1);manacher();for( int i = 1; i <= n; i++ ) q[i] = i;std::sort(q+1,q+n+1,cmp); int now = 1;for( int i = 1; i <= n; i++ ){while( now <= n && q[now]-p[q[now]] <= i ){t.insert(q[now]); now++;}set<int>::iterator tmp = t.upper_bound(i+p[i]/2);if( tmp != t.begin() ) ans = max(ans,(*--tmp-i)*4); }printf("%d",ans);return 0;}


原创粉丝点击