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",n,0);
continue;
}
if(!C(1)) {
printf("none\n");
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\n");
else printf("%d %d\n",ans,idx);
}
return 0;
}
------------