您的位置:首页 > 其它

后缀数组模板

2016-05-23 14:32 281 查看
刘汝佳的代码会RE!!!被坑了3小时!

以下模板自带注释

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 100005
#define rank RANK
int n;
char str[maxn];
int cnt[maxn];
int t1[maxn],t2[maxn];
int sa[maxn];
int rank[maxn];
int height[maxn];
void build()
{
int *x=t1,*y=t2;
int m=26;
for(int i=0;i<n;i++) cnt[x[i]=(str[i]-'a')]++;
for(int i=1;i<m;i++) cnt[i]+=cnt[i-1];
for(int i=n-1;i>=0;i--) sa[--cnt[x[i]]]=i;
for(int k=1;k<=n;k<<=1)
{
int p=0;
for(int i=n-1;i>=n-k;i--) y[p++]=i;
for(int i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
//y[i]:position of the suffix having the i-th "next k num",similar to sa
memset(cnt,0,sizeof(cnt));
for(int i=0;i<p;i++) cnt[x[y[i]]]++;
for(int i=1;i<m;i++) cnt[i]+=cnt[i-1];
for(int i=p-1;i>=0;i--) sa[--cnt[x[y[i]]]]=y[i];
//give a higher rank to suffix with larger second keyword when having same first one
swap(x,y);//this time,y stores the information
p=0;
for(int i=0;i<n;i++)
x[sa[i]]= (!i||y[sa[i]]!=y[sa[i-1]]||y[sa[i]+k]!=y[sa[i-1]+k]) ? \
p++:p-1;
if(p>=n) break;
m=p;
}
for(int i=0;i<n;i++) rank[sa[i]]=i;
int k=0;
for(int i=0;i<n;i++)
{
if(k) k--;
if(rank[i]==0) continue;
int j=sa[rank[i]-1];
while(str[i+k]==str[j+k]) k++;
height[rank[i]]=k;
}

}
int main()
{
//freopen(".in","r",stdin);
scanf("%d",&n);
scanf("%s",str);
build();
for(int i=0;i<n;i++) printf("%d ",sa[i]);
putchar('\n');
for(int i=0;i<n;i++) printf("%d ",rank[i]+1);
putchar('\n');
for(int i=1;i<n;i++) printf("%d ",height[i]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: