求解为什么这样做不对
查看原帖
求解为什么这样做不对
226113
火羽白日生楼主2021/5/24 08:16

rt

思路就是求出以 ii 为左右端点的最长回文串长度 li,ril_i,r_i,然后枚举每个断点#判断

但是 WAWA 了两个点

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rint register int

using namespace std;

inline int read(){
	int w=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
	while(ch>='0'&&ch<='9'){w=(w<<3)+(w<<1)+(ch^48); ch=getchar();}
	return w*f;
}

const int maxn=5e5+5;
const ull base=13131;

int n,ans;
ull pw[maxn<<1],h[maxn<<1];
char s[maxn],str[maxn<<1];
namespace Manacher{
	int p[maxn<<1],l[maxn<<1],r[maxn<<1],cnt,mid,R;
	inline void rebuild(){
		str[++cnt]='~',str[++cnt]='#';
		for(int i=1;i<=n;i++) str[++cnt]=s[i],str[++cnt]='#';
		str[++cnt]='@';
		n=cnt-1;
	}
	inline void manacher(){
		for(int i=1;i<=n;i++){
			if(i<=R) p[i]=min(p[mid*2-i],R-i+1);
			else p[i]=1;
			while(str[i-p[i]]==str[i+p[i]]) p[i]++;
			if(i+p[i]>R) R=i+p[i]-1,mid=i;
			l[i-p[i]+1]=max(l[i-p[i]+1],p[i]-1);
			r[i+p[i]-1]=max(r[i+p[i]-1],p[i]-1);
		}
	}
}using namespace Manacher;
inline void init(){
	pw[0]=1; h[0]=0;
	for(int i=1;i<maxn*2;i++) pw[i]=pw[i-1]*base;
}
inline ull gethash(int l,int r){
	return (h[r]-h[l-1]*pw[r-l+1]);
}

int main(){
	n=read();
	scanf("%s",s+1);
	rebuild(); manacher(); init();
	for(int i=1;i<=n;i++) h[i]=h[i-1]*base+(ull)(str[i]+1);
	for(int i=1;i<=n;i+=2) l[i]=max(l[i],l[i-2]-2);
	for(int i=n;i>=1;i-=2) r[i]=max(r[i],r[i+2]-2);
	for(int i=2;i<=n;i+=2) 
		if(l[i] && r[i] && l[i]==r[i] && l[i]%2==0 && r[i]%2==0 && gethash(i+1,i+2*l[i]-1)==gethash(i-2*r[i]+1,i-1))
				ans=max(ans,l[i]+r[i]);
	printf("%d\n",ans);
	return 0;
}

2021/5/24 08:16
加载中...