poj 1743
后缀数组,经典,height数组的深入理解,想象一下山的形状就明白了。
代码:
#include<iostream>
#include<fstream>
using namespace std;
#define N 20003
int sa[N],sa1[N],rank[N],rank1[N],c[N],h[N],m[N];
int n,pow;
int cmp(const void *a,const void *b){
int x=*(int*)a;
int y=*(int*)b;
if(rank[x]!=rank[y])
return(1);
else
if(rank[x+pow]!=rank[y+pow])
return(1);
else
return(0);
}
void creat(){
int i,j,k;
for(i=0;i<500;i++)
c[i]=0;
for(i=0;i<n;i++)
c[m[i]]++;
for(i=1;i<500;i++)
c[i]+=c[i-1];
for(i=n-1;i>=0;i--)
sa[--c[m[i]]]=i;
for(i=0,j=0;i<n;i++)
{
if(i>0&&m[sa[i]]!=m[sa[i-1]])
j++;
rank[sa[i]]=j;
}
for(pow=1;pow<n;pow*=2)
{
for(i=0;i<n;i++)
c[i]=0;
for(i=0;i<n;i++)
if(sa[i]+pow<n)
c[rank[sa[i]+pow]]++;
else
c[rank[sa[i]]]++;
for(i=1;i<n;i++)
c[i]+=c[i-1];
for(i=n-1;i>=0;i--)
if(sa[i]+pow<n)
sa1[--c[rank[sa[i]+pow]]]=sa[i];
else
sa1[--c[rank[sa[i]]]]=sa[i];
for(i=0;i<n;i++)
c[i]=0;
for(i=0;i<n;i++)
c[rank[sa1[i]]]++;
for(i=1;i<n;i++)
c[i]+=c[i-1];
for(i=n-1;i>=0;i--)
sa[--c[rank[sa1[i]]]]=sa1[i];
for(i=0,j=0;i<n;i++)
{
if(i>0&&cmp(&sa[i],&sa[i-1])!=0)
j++;
rank1[sa[i]]=j;
}
for(i=0;i<n;i++)
rank[i]=rank1[i];
}
}
void height(){
int i,j,k=0;
for(i=0;i<n;i++)
{
if(rank[i]==0)
h[rank[i]]=k=0;
else
{
if(k>0) k--;
j=sa[rank[i]-1];
for(;m[i+k]==m[j+k];k++);
h[rank[i]]=k;
}
}
}
int judge(int len){
int i,mi,ma;
mi=sa[0];ma=sa[0];
for(i=1;i<n;i++)
{
if(h[i]>=len)
{
if(sa[i]>ma)
ma=sa[i];
if(sa[i]<mi)
mi=sa[i];
if(ma-mi>=len)
return(1);
}
else
{
mi=sa[i];ma=sa[i];
}
}
return(0);
}
int main(){
int i,j,k,mid;
//ifstream cin("in.txt");
while(1){
scanf("%d",&n);
if(n==0) return(0);
scanf("%d",&j);
n--;
for(i=0;i<n;i++)
{
scanf("%d",&m[i]);
k=m[i];
m[i]=m[i]-j+100;
j=k;
}
m[n]=0;
n++;
creat();
height();
i=0;j=n;
while(i<=j)
{
mid=(i+j)/2;
if(judge(mid)) i=mid+1;
else
j=mid-1;
}
if(j>=4)
cout<<j+1<<endl;
else
cout<<0<<endl;
}
return(0);
}
浙公网安备 33010602011771号