POJ 3882 TLE 需后缀数组
------------
const int SEED = 13331; const int MAX_N = 50000 + 10; char s[MAX_N]; struct HASH{ ULL H[MAX_N]; ULL XL[MAX_N]; int len; HASH(){} void build(char *s){ len=strlen(s); H[len]=0; XL[0]=1; for (int i=len-1;i>=0;i--){ H[i]=H[i+1]*SEED+s[i]; XL[len-i]=XL[len-i-1]*SEED; } } ULL hash(int i,int L){ return H[i]-H[i+L]*XL[L]; } }hs; int n,m; ULL a[MAX_N]; int id[MAX_N]; int idx; bool cmp(int x,int y){ if (a[x]==a[y]) return x<y; return a[x]<a[y]; } bool C(int L) { int cnt=0,sum=1; idx=-1; for (int i=0;i+L<=n;i++) { a[cnt]=hs.hash(i,L); id[cnt++]=i; } sort(id,id+cnt,cmp); for (int i=1;i<cnt;i++) { if (a[id[i]]==a[id[i-1]]) { sum++; if (sum>=m) idx=max(idx,id[i]); } else sum=1; } return idx>=0; } int main(){ while (~scanf("%d",&m)) { if (m==0) break; scanf("%s",s); hs.build(s); n=strlen(s); if(m==1) { printf("%d %d ",n,0); continue; } if(!C(1)) { printf("none "); continue; } int l=1,r=n; int ans=0; while (l<=r) { int mid=(l+r)>>1; if (C(mid)) { ans=mid; l=mid+1; } else r=mid-1; } C(ans); if (ans==0) printf("none "); else printf("%d %d ",ans,idx); } return 0; }
------------