spoj-687(后缀数组+RMQ)
题目:
A string s is called an (k,l)-repeat if s is obtained by concatenating k>=1 times some seed string t with length l>=1. For example, the string
s = abaabaabaaba
is a (4,3)-repeat with t = aba as its seed string. That is, the seed string t is 3 characters long, and the whole string s is obtained by repeating t 4 times.
Write a program for the following task: Your program is given a long string u consisting of characters ‘a’ and/or ‘b’ as input. Your program must find some (k,l)-repeat that occurs as substring within u with k as large as possible. For example, the input string
u = babbabaabaabaabab
contains the underlined (4,3)-repeat s starting at position 5. Since u contains no other contiguous substring with more than 4 repeats, your program must output the maximum k.
Input
In the first line of the input contains H- the number of test cases (H <= 20). H test cases follow. First line of each test cases is n - length of the input string (n <= 50000), The next n lines contain the input string, one character (either ‘a’ or ‘b’) per line, in order.
Output
For each test cases, you should write exactly one interger k in a line - the repeat count that is maximized.
Example
Input:
1
17
b
a
b
b
a
b
a
a
b
a
a
b
a
a
b
a
b
Output:
4
since a (4, 3)-repeat is found starting at the 5th character of the input string.
啊,,wa了好几次又re了都是因为自己的zz细节错误啊。。。按照论文里的套板子就好。。。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<complex>
#include<queue>
#define T 111111
using namespace std;
char s[T],ccc[T];
int t1[T],t2[T],cc[T],x[T],sa[T],rnk[T],height[T];
int f[T][20];
int len;
int ans;
bool cmp(int *y,int a,int b,int k)
{
int a1=y[a];
int b1=y[b];
int a2=a+k>=len ? -1:y[a+k];
int b2=b+k>=len ? -1:y[b+k];
return a1==b1 && a2==b2;
}
int make_sa()
{
int *x=t1,*y=t2;
int m=255;
for(int i=0; i<m; i++) cc[i]=0;
for(int i=0; i<len; i++) ++cc[x[i]=s[i]];
for(int i=1; i<m; i++) cc[i]+=cc[i-1];
for(int i=len-1; i>=0; i--) sa[--cc[x[i]]]=i;
for(int k=1; k<=len; k<<=1)
{
int p=0;
for(int i=len-k; i<len; i++) y[p++]=i;
for(int i=0; i<len; i++)
if( sa[i]>=k ) y[p++]=sa[i]-k;
for(int i=0; i<m; i++) cc[i]=0;
for(int i=0; i<len; i++) ++cc[x[y[i]]];
for(int i=1; i<m; i++) cc[i]+=cc[i-1];
for(int i=len-1; i>=0; i--) sa[--cc[x[y[i]]]]=y[i];
swap(x,y);
m=1; x[sa[0]]=0;
for(int i=1; i<len; i++)
x[sa[i]]=cmp(y,sa[i],sa[i-1],k) ? m-1:m++;
if( m>=len ) break;
}
}
void make_height()
{
for(int i=0; i<len; i++) rnk[sa[i]]=i;
height[0]=0;
int k=0;
for(int i=0; i<len; i++)
{
if(!rnk[i]) continue;
int j=sa[rnk[i]-1];
if(k) k--;
while(s[i+k]==s[j+k]) k++;
height[rnk[i]]=k;
}
}
void rmq()
{
for(int i=0;i<len;i++){
f[i][0]=height[i];
}
int nlog=int(log(double(len))/log(2.0));
for(int j=1;j<=nlog;j++){
for(int i=0;i<len;i++){
if(i+(1<<j)<=len){
f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
}
}
}
int qrmq(int l,int r)
{
l=rnk[l];
r=rnk[r];
if(l>r){
int h;
h=l;l=r;r=h;
}
l++;
int nlog=int (log(double(r-l+1))/log(2.0));
return min(f[l][nlog],f[r-(1<<nlog)+1][nlog]);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&len);
int ii=0;
while(ii!=len){
scanf("%s",ccc);
s[ii++]=ccc[0];
}
s[ii]='\0';
make_sa();
make_height();
rmq();
ans=0;
for(int k=1;k<len;k++){
for(int i=0;i+k<len;i+=k){
int n=qrmq(i,i+k);
//cout<<"n:"<<n<<endl;
int sum=(n/k)+1;
int pos=i-(k-n%k);
if(pos>=0&&n%k!=0) {
if(qrmq(pos,pos+k)>=k)
sum++;
}
ans=max(ans,sum);
}
}
printf("%d\n",ans);
}
return 0;
}