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);
}
浙公网安备 33010602011771号