void dc3(int *r,int *sa,int n,int m) // r为待匹配数组 n为总长度 m为字符范围
{
int i,j,*rn=r+n,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p;
r[n]=r[n+1]=0;
for(i=0;i
sort(r+1,wb,wa,tbc,m);
sort(r,wa,wb,tbc,m);
for(p=1,rn[F(wb[0])]=0,i=1;i
if(p
sort(r,wb,wa,ta,m);
for(i=0;i
for(;i
}
int rank[maxn],height[maxn];
void calheight(int *r,int *sa,int n) // 求height数组。
{
int i,j,k=0;
for(i=1;i<=n;i++) rank[sa[i]]=i;
for(i=0;i
return;
}
int RMQ[maxn];
int mm[maxn];
int best[20][maxn];//best[i][j] 表示从j开始的长度为2的i次方的一段元素的最小值
void initRMQ(int n)
{
int i,j,a,b;
for(mm[0]=-1,i=1;i<=n;i++)
mm[i]=((i&(i-1))==0) mm[i-1]+1:mm[i-1];
for(i=1;i<=n;i++) best[0][i]=i;
for(i=1;i<=mm[n];i++)
for(j=1;j<=n+1-(1< {
a=best[i-1][j];
b=best[i-1][j+(1<<(i-1))];
if(RMQ[a]
}
return;
}
int askRMQ(int a,int b)//询问a,b后缀的最长公共前缀
{
int t;
t=mm[b-a+1];b-=(1<
return RMQ[a]
int lcp(int a,int b)
{
int t;
a=rank[a];b=rank[b];
if(a>b) {t=a;a=b;b=t;}
return(height[askRMQ(a+1,b)]);
}
char c;
int r[maxn*3],sa[maxn*3];
int ans[maxn];
char str[maxn*3];
int main()
{
int i,j,n,cas=0;
{
n=strlen(str);
if(n==1&&str[0]=='#') break;
for(i=0;i
dc3(r,sa,n+1,30);//千万注意是n+1
calheight(r,sa,n);
for(i=1;i<=n;i++) RMQ[i]=height[i];
initRMQ(n);
/*
for(i=0; i
printf("\n");
for(i=0; i
*/
int l,mmax=-1,cnt,pos,t=0;
for(l=1;l
for(i=0;i+l
int k=lcp(i,i+l);
cnt=k/l+1;
pos=k%l;
pos=l-pos;
pos=i-pos;
if(pos>=0&&k%l!=0&&lcp(pos,pos+l)>=k) cnt++;////
if(cnt>mmax)
{
mmax=cnt;
t=0;
ans[t++]=l;
}
else if(cnt==mmax)
{
ans[t++]=l;
}
}
}
int flag=0,start;
for(i=1;i<=n;i++)
{
for(j=0;j
l=ans[j];
if(lcp(sa[i],sa[i]+l)>=(mmax-1)*l)
{
start=sa[i];
l=l*mmax;
flag=1;
break;
}
}
if(flag) break;
}
printf("Case %d: ",++cas);
for (int i=0;i
}
return 0;
}
#include
#include
#define maxn 1000001
#define F(x) ((x)/3+((x)%3==1 0:tb))
#define G(x) ((x)
int c0(int *r,int a,int b)
{return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+