suxxsfe

一言(ヒトコト)

P4555 最长双回文串

https://www.luogu.com.cn/problem/P4555
https://darkbzoj.tk/problem/2565

\(T=XY\),其中 \(X,Y\) 均为回文串,求 \(T\) 的最大长度

首先把每两个原有字符的间隙填充上其他字符,然后可以用 manacher 求出每个点的最大回文半径 \(len_i\),此时这个回文半径对应的回文串的实际长度是 \(len_i-1\)
因为要求的是两个回文串拼起来,所以可以求 \(l_i,r_i\) 分表表示以 \(i\) 开头,结尾的回文串最大长度,答案就是 \(\max\{l_i+r_i\}\)

当求出 \(len_i\) 时,这样更新:\(l_{i-len_i+1}=\max(l_{i-len_i+1},len_i-1),r_{i+len_i-1}=\max(r_{i+len_i-1},len_i-1)\)
注意这里 \(l,r\) 的下标是以填充后的字符串下标为准,而值是在原有字符串中的长度,也就是此时的 \(len_i-1\)
而我们要考虑的也只是当 \(s_i\) 是填充进来的字符时,\(l_i,r_i\) 的值,因为此时他才满足向左向右都是原串的一个回文子串

但,这样只是更新了最大长度,比如对于 \(len_i'<len_i\)\(l_{i-len_i'+1}\) 也可以用 \(len_i'-1\) 来更新,但这里并没有更新到
所以做完 manacher 以后,还要分别对 \(l,r\) 处理:对于每一个填充进来的 \(s_i\)\(l_i=\max(l_i,l_{i-2}-2),r_i=\max(r_i,r_{i+2}-2)\)
也就是以 \(i\) 开头的,就考虑一下以 \(i-2\) 开头的(上一个填充进来的字符),用它的长度减去 \(2\)(减去一头一尾)来更新。以 \(i\) 结尾的也是同理

最后考虑这些填充进来的 \(s_i\),取 \(\max\{l_i+r_i\}\) 为答案

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
	register int x=0;register int y=1;
	register char c=std::getchar();
	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
	return y?x:-x;
}
char in[100005],s[200005];
int n;
int len[200005];
int l[200005],r[200005];
int main(){
	scanf("%s",in+1);
	int lenin=std::strlen(in+1);
	s[0]=0;s[1]=2;n=1;
	for(reg int i=1;i<=lenin;i++) s[++n]=in[i],s[++n]=2;
	s[n+1]=1;
	int pos=0,max=0;
	for(reg int i=1;i<=n;i++){
		if(pos+max-1<i) len[i]=1;
		else len[i]=std::min(len[pos+pos-i],pos+max-i);
		while(s[i+len[i]]==s[i-len[i]]) len[i]++;
		if(i+len[i]-1>=pos+max-1) pos=i,max=len[i];
		l[i-len[i]+1]=std::max(l[i-len[i]+1],len[i]-1);
		r[i+len[i]-1]=std::max(r[i+len[i]-1],len[i]-1);
	}
	for(reg int i=1;i<=n;i+=2) l[i]=std::max(l[i],l[i-2]-2);
	for(reg int i=n;i>0;i-=2) r[i]=std::max(r[i],r[i+2]-2);
	reg int ans=0;
	for(reg int i=1;i<=n;i+=2) ans=std::max(ans,(l[i]&&r[i])*(l[i]+r[i]));
	printf("%d",ans);
	return 0;
}
posted @ 2020-07-13 21:27  suxxsfe  阅读(289)  评论(0编辑  收藏  举报