60分求助
查看原帖
60分求助
416975
sbno333楼主2024/3/24 22:15

4569 全WA了。

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
string s;
int rr[2000009];
int zz[2000009];
int le[2000009];//维护最长的le[i]使得前i个字符的长度为le[i]后缀存在另一个与该后缀相同的后缀
void mc(){//马拉车
	for(int t=1,r=0,mid=0;t<=n;++t){
	    if(t<=r) rr[t]=min(rr[(mid<<1)-t],r-t+1);
	    while(s[t-rr[t]]==s[t+rr[t]]) ++rr[t];
	    if(rr[t]+t>r) r=rr[t]+t-1,mid=t;
      }
}
int xb[2009];
void pmk(){
	zz[1]=0;//最长的后缀最靠后的下标
	le[1]=0;
	xb[s[1]]=1;
	for(int i=2;i<=n;i++){
		if(s[i]==s[zz[i-1]+1]){
			zz[i]=zz[i-1]+1;
			le[i]=le[i-1]+1;
		}else{
			zz[i]=xb[s[i]];
			if(xb[s[i]])le[i]=1;
		}
		xb[s[i]]=i;
	}
}
int q1[2000009];//r[i]+i-1
int q2[2000009];//i
int h=1,t;
signed main(){
	cin>>n;
	cin>>s;
	s='|'+s;
	mc();
	pmk();
	int ans;
	ans=0;
	for(int i=1;i<=n;i++){
		q1[++t]=rr[i]+i-1;//维护一个队列
		q2[t]=i;
		int z;
		z=i-(le[i]+1)/2+1;//最长后缀的中间
		while(h<=t&&(q1[h]-i<0||q2[h]<z)){
			++h;
		}
		if(h<=t)
		ans=max(ans,i-q2[h]+1);
	}
	cout<<ans;
	return 0;
} 
2024/3/24 22:15
加载中...