您的位置:首页 > 其它

[模板]后缀数组

2015-04-01 09:44 183 查看
这是lrj的后缀数组模板

int s[MAXN+10];//char
int sa[MAXN+10],t[MAXN+10],t2[MAXN+10],c[MAXN+10];
void build_sa(int m)
{
int i,*x=t,*y=t2;
for(i=0;i<m;i++) c[i]=0;
for(i=0;i<n;i++) c[x[i]=s[i]]++;
for(i=1;i<m;i++) c[i]+=c[i-1];
for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i;

for(int k=1;k<=n;k<<=1)
{
int p=0;
for(i=n-k;i<n;i++) y[p++]=i;
for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;

for(i=0;i<m;i++) c[i]=0;
for(i=0;i<n;i++) c[x[y[i]]]++;
for(i=1;i<m;i++) c[i]+=c[i-1];
for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];

swap(x,y);
p=1;
x[sa[0]]=0;
for(i=1;i<n;i++)
if(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])
x[sa[i]]=p-1;
else x[sa[i]]=p++;
if(p>=n) break;
m=p;
}
}
int Rank[MAXN+10],h[MAXN+10];
void getheight()
{
int i,k=0;
for(i=0;i<n;i++) Rank[sa[i]]=i;
for(i=0;i<n;i++)
{
if(k) k--;
if(!Rank[i]) continue;
int j=sa[Rank[i]-1];
while(s[i+k]==s[j+k]) k++;
h[Rank[i]]=k;
}
}


后缀数组的LCP

int LOG(int x)
{
int res=0;
while(x)
{
x>>=1;
res++;
}
return res-1;
}
int sparse_table[MAXN+10][MAXLOG];
void pre()
{
int i,j;
for(i=0;i<n;i++)
sparse_table[i][0]=h[i];
for(j=1;j<=MAXLOG;j++)
{
int up=n-(1<<j);
for(i=0;i<up;i++)
sparse_table[i][j]=min(sparse_table[i][j-1],sparse_table[i+(1<<(j-1))][j-1]);
}
}
int LCP(int x,int y)
{
x=Rank[x];
y=Rank[y];
Log=LOG(y-x+1);
return min(sparse_table[x][Log],sparse_table[y-(1<<Log)+1][Log]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: