感觉学习了后缀数组整个人都好了,于是看到这题想都没想就开始写,然而事实并不如意,TTTTTTTTQAQQQQQQ,赶快吧O复杂度换成T复杂度,真是玄学4亿多= =
放下个TLE的版本,还有就是被之前学的版本坑了,在原串和反串之间加入了特殊符号之后,height数组的最大值就已经是答案了
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #define LL long long #define fo(i,a,b) for(int i=a;i<=b;i++) #define down(i,a,b) for(int i=a;i>=b;i--) using namespace std; #define N 220005 #define M 30 char s[N]; int sa[N],height[N],ra[N]; int n,ans; int C[N]; void getsa(int m) { fo(i,0,n)ra[i]=0,sa[i]=0,height[i]=0; fo(i,0,m)C[i]=0; fo(i,1,n)ra[i]=s[i]-96,C[ra[i]]++; fo(i,1,m)C[i]+=C[i-1]; // cout<<n<<' '<<ra[n]<<' '<<C[ra[n]]<<' '<<sa[C[ra[n]]]<<endl; down(i,n,1)sa[C[ra[i]]--]=i; for(int k=1;k<=n;k<<=1) { int p=0; fo(i,n-k+1,n)height[++p]=i; fo(i,1,n)if(sa[i]>k)height[++p]=sa[i]-k; fo(i,0,m)C[i]=0; fo(i,1,n)C[ra[height[i]]]++; fo(i,1,m)C[i]+=C[i-1]; down(i,n,1)sa[C[ra[height[i]]]--]=height[i]; swap(ra,height);p=0;ra[sa[1]]=++p; fo(i,2,n) if(height[sa[i]]==height[sa[i-1]]&&height[sa[i]+k]==height[sa[i-1]+k]) ra[sa[i]]=p;else ra[sa[i]]=++p;//cout<<"Run:"<<k<<endl; if(n==p)break; m=p; } // fo(i,1,n)fo(j,sa[i],n)cout<<s[j];cout<<endl; } void getheight() { int i=0,j=0,k=0; for(i=1;i<=n;height[ra[i++]]=k,ans=max(ans,k)) for(k?k--:0,j=sa[ra[i]-1];s[i+k]==s[j+k];k++); // fo(i,1,n)cout<<height[i]<<' ';cout<<endl; } int main() { while(scanf("%s",s+1)!=EOF) { n=strlen(s+1);int len=n;s[n+1]='z'+1;ans=0; for(int i=1,j=2*n+1;i<j;i++,j--)s[j]=s[i];n<<=1;n++; getsa(27); getheight(); // fo(i,2,n)ans=max(height[i],ans); printf("%d\n",ans); } return 0; }