2333
这个就是把每一个串正反连起来,然后所有串连起来,注意中间加上分割的分开(应该开的比z大,而且蛋疼的我写int)
然后搞出后缀数组,二分一个答案,然后再height数组判断一下就好了
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #define N 100005 5 #define inf 0x3f3f3f3f 6 #define LL long long 7 #define eps 1e-8 8 using namespace std; 9 inline int ra() 10 { 11 int x=0,f=1; char ch=getchar(); 12 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 13 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 14 return x*f; 15 } 16 17 const int maxn=10005; 18 19 int sa[2][maxn],rank[2][maxn],v[maxn],height[maxn],p=0,q=1; 20 int n,len,id[maxn]; 21 int a[maxn]; 22 bool vis[105]; 23 24 void cal_sa(int sa[N], int rank[N], int Sa[N], int Rank[N], int k) 25 { 26 for (int i=1; i<=n; i++) v[rank[sa[i]]]=i; 27 for (int i=n; i>=1; i--) if (sa[i]>k) Sa[v[rank[sa[i]-k]]--]=sa[i]-k; 28 for (int i=n-k+1; i<=n; i++) Sa[v[rank[i]]--]=i; 29 for (int i=1; i<=n; i++) Rank[Sa[i]]=Rank[Sa[i-1]]+(rank[Sa[i]]!=rank[Sa[i-1]] || rank[Sa[i]+k]!=rank[Sa[i-1]+k]); 30 } 31 void get_height() 32 { 33 int k=0; 34 for (int i=1; i<=n; i++) 35 { 36 if (rank[p][i]==1) height[1]=0; 37 else 38 { 39 int j=sa[p][rank[p][i]-1]; 40 while (a[j+k]==a[i+k]) k++; 41 height[rank[p][i]]=k; 42 if (k) k--; 43 } 44 } 45 } 46 void work() 47 { 48 for (int i=1; i<=n; i++) v[a[i]]++; 49 for (int i=1; i<=300; i++) v[i]+=v[i-1]; 50 for (int i=1; i<=n; i++) sa[p][v[a[i]]--]=i; 51 for (int i=1; i<=n; i++) rank[p][sa[p][i]]=rank[p][sa[p][i-1]]+(a[sa[p][i]]!=a[sa[p][i-1]]); 52 for (int k=1; k<n; k<<=1,swap(p,q)) cal_sa(sa[p],rank[p],sa[q],rank[q],k); 53 get_height(); 54 } 55 56 bool check(int L) 57 { 58 int tot=0; memset(vis,0,sizeof(vis)); 59 for (int i=2; i<=n; i++) 60 { 61 if (height[i]<L) 62 { 63 tot=0; memset(vis,0,sizeof(vis)); 64 continue; 65 } 66 if (!vis[id[sa[p][i-1]]]) vis[id[sa[p][i-1]]]=1,tot++; 67 if (!vis[id[sa[p][i]]]) vis[id[sa[p][i]]]=1,tot++; 68 if (tot>=len) return 1; 69 } 70 return 0; 71 } 72 void solve() 73 { 74 int l=0,r=n,ans=0; 75 while (l<=r) 76 { 77 int mid=l+r>>1; 78 if (check(mid)) ans=mid,l=mid+1; else r=mid-1; 79 } 80 printf("%d ",ans); 81 } 82 int main(int argc, char const *argv[]) 83 { 84 int T=ra(); 85 while (T--) 86 { 87 memset(v,0,sizeof(v)); n=ra(); len=0; 88 for (int i=1; i<=n; i++) 89 { 90 char ch[105]; scanf("%s",ch+1); 91 for (int j=1; j<=strlen(ch+1); j++) 92 a[++len]=ch[j],id[len]=i; 93 a[++len]=150+(i-1)*2,id[len]=i; 94 for (int j=strlen(ch+1); j>=1; j--) 95 a[++len]=ch[j],id[len]=i; 96 a[++len]=150+(i-1)*2+1,id[len]=i; 97 } 98 swap(n,len); work(); 99 solve(); 100 } 101 return 0; 102 }