这题说的是给了一串字符 我们要将这个字符 中找出至少出现m次的最长字符串 一个字符课多次使用
利用后缀数组计算最长的lcp
这里有一个点 记得将后缀数组中加入一个空串 如果遇到全部相同的字符时 没办法 判断 倒数第二个和 第三个的大小 因此他们就会被遗漏

#include <iostream> #include <algorithm> #include <cstdio> #include <vector> #include <string.h> using namespace std; const int maxn =100005; struct SuffixArray { int s[maxn]; int sa[maxn]; int t[maxn],t2[maxn],c[maxn]; int rank[maxn],lcp[maxn]; int n; void build(int m) { int *x=t,*y=t2,i; for(i=0; i<m; i++ )c[i]=0; for(i=0; i<n; i++)c[ x[i]=s[i] ]++; for(i=1; i<m; i++)c[i]+=c[i-1]; for(i=n-1; i>=0; i--)sa[ --c[ x[i] ] ]=i; for(int k=1; k<=n; k<<=1) { int p=0; for(i=n-k; i<n; i++) y[ p++ ]=i; for(i=0; i<n; i++)if(sa[i]>=k) y[p++ ]= sa[i]-k; for(i=0; i<m; i++) c[ i ]=0; for(i=0; i<n; i++) c[ x[ y[i] ] ]++; for(i=1; i<m; i++)c[i]+=c[i-1]; for(i=n-1; i>=0; i--) sa[ -- c[ x[ y[ i ] ] ] ]=y[i]; for(i=0; i<n; i++)rank[ sa[i] ]=i; p=1; swap(x,y); x[ sa[0] ] =0; for(int i=1; i<n; i++) x[ sa[i] ]= y[ sa[i] ]==y[ sa[i-1] ]&&y[ sa[i]+k ]==y[ sa[i-1]+k ] ?p-1:p++; if(p>=n)break; m=p; } } void getLcp() { int i,k=0; for(i=0; i<n; i++)rank[ sa[ i ] ] =i; for(i=0; i<n; i++) { if(k)k--; int j=sa[ rank[i]-1 ]; while(s[j+k]==s[i+k])k++; lcp[ rank[i] ]=k; } } }sa; bool solve(int len,int m) { int L=0; for(int R=1; R<=sa.n; R++) { if(sa.lcp[R]<len||R==sa.n) { if( R-L >= m )return true; L=R; } } return false; } int look(int L, int R) { int ans=-1; for(int i=L; i<R; i++) { ans=max(sa.sa[i],ans); } return ans; } int select(int len, int m) { int L=0,ad=-1; for(int R=1; R<=sa.n; R++) { if(sa.lcp[R]<len||R==sa.n) { if(R-L>=m) { ad=max(look(L,R),ad); } L=R; } } return ad; } char ss[maxn]; int main() { int m; while(scanf("%d",&m)==1) { if(m==0)break; scanf("%s",ss); sa.n=strlen(ss); for(int i=0; i<sa.n; i++) { sa.s[i]= ss[i]-'a'+1; } if(m==1) { printf("%d %d ",sa.n,0); continue; } sa.s[sa.n]=0; sa.n++; sa.build(27); sa.getLcp(); if(solve(1,m)==false) { puts("none");continue; } int L=1,R=sa.n,ans; while(L<=R) { int mid=(R+L)/2; if(solve(mid,m)){ ans=mid; L=mid+1; }else R=mid-1; } printf("%d %d ",ans,select(ans,m)); } return 0; }