站外题求助
  • 板块学术版
  • 楼主wyf_sinon
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/3/9 12:55
  • 上次更新2024/3/9 15:04:06
查看原帖
站外题求助
540177
wyf_sinon楼主2024/3/9 12:55

题干大意:求最长回文子串长度

蒟蒻写的nlogn却T了(范围是1e6,最多三十个输入

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int p=131,N=1e6+10;
int n;
int h[N];
int d[N];
int pw[N];
int H(int l,int r) {
	return h[r]-h[l-1]*pw[r-l+1];
}
int D(int l,int r) {
	return d[r]-d[l-1]*pw[r-l+1];
}
void it()
{
	pw[0]=1;for(int i=1;i<N;i++) pw[i]=pw[i-1]*p;
}
bool ch(char s[])
{
	string ss="END";
	for(int i=0;i<3;i++) if(s[i]!=ss[i]) return true ;
	return false;
}
signed main() {
	char s[N];
	int id=0;
	it();
	while(1) {
		id++;
		scanf("%s",s);
		if(!ch(s)) break;
		string sn;
		int ans=0;
		int sl=strlen(s);
		for(int i=0; i<sl; i++) sn=sn+"#"+s[i];
		sn+="#";
		h[0]=1;
		d[0]=1;
		int lenn=sl*2+1;
		for(int i=1; i<=lenn; i++) h[i]=h[i-1]*p+sn[i-1];//正向
		for(int i=1; i<=lenn; i++) d[i]=d[i-1]*p+sn[lenn-i];//反向
		for(int i=0; i<lenn; i++) 
		{
			int l=1,r=min(i+1,lenn-i);
			if(r<ans) continue;
			int len=1;
			while(l<=r) {
				int mid=(l+r)>>1;
				if( H(i-mid+2,i+1) == D(lenn-(i+mid-1),lenn-i) ) {
					len=mid;
					l=mid+1;
				} 
				else r=mid-1;
			}
			ans=max(ans,len) ;
		}
		printf("Case %lld: %lld\n",id,ans-1);
	}
}
2024/3/9 12:55
加载中...