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);
}

posted on 2011-03-10 18:01  宇宙吾心  阅读(316)  评论(0)    收藏  举报

导航