poj 3080

后缀数组,二分求多串子串,height数组山的结构。

#include<iostream>
#include<fstream>

using namespace std;
#define N 620

int sa[N],sa1[N],rank[N],rank1[N],c[N],h[N];
char m[N];

int n,pow,count;

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 v[11];
int f[700];
int ans;

int judge(int len){
	int i;
	int sum=0;
	for(i=1;i<n;i++)
	{
		if(h[i]>=len)
		{
			if(v[f[sa[i-1]]]==0)
			{
				v[f[sa[i-1]]]=1;
				sum++;
				if(sum==count)
				{
					ans=sa[i-1];
					return 1;
				}
			}
			if(v[f[sa[i]]]==0)
			{
				v[f[sa[i]]]=1;
				sum++;
				if(sum==count)
				{
					ans=sa[i];
					return 1;
				}
			}
		}
		else
		{
			sum=0;
			memset(v,0,sizeof(v));
			
		}
	}

	return(0);
}


int main(){
	int i,j,k,mid;
//	ifstream cin("in.txt");
	int K;
	cin>>K;
	while(K--){

		cin>>count;
		n=0;
		for(i=1;i<=count;i++)
		{
			for(j=1;j<=60;j++)
			{
				cin>>m[n++];
				f[n-1]=i;
				
			}
			m[n++]=count-i;
		}
	

	creat();
	height();
	i=0;j=n;
	while(i<=j)
	{
		mid=(i+j)/2;

		memset(v,0,sizeof(v));
		if(judge(mid)) i=mid+1;
		else
			j=mid-1;
	}
	if(j<3)
		cout<<"no significant commonalities"<<endl;
	else
	{
		for(i=ans;i<ans+j;i++)
			cout<<m[i];
		cout<<endl;

	}

	}

	return(0);
}

posted on 2011-03-13 14:06  宇宙吾心  阅读(673)  评论(0)    收藏  举报

导航