题干大意:求最长回文子串长度
蒟蒻写的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);
}
}