您的位置:首页 > 其它

【POJ2774】Long Long Message,第一次的后缀数组

2016-05-21 20:56 357 查看
Time:2016.05.21

Author:xiaoyimi

转载注明出处谢谢

传送门

思路:没什么值得说的,大家想看思路的话还是去看大牛们的吧,磨了将近一天的后缀数组,基本按照模板打得,最后发现有些bug,又去博采众长才艰难的A掉,WA了不知道多少次啊啊啊

注意:

使用指针交换数组元素是很快的 ——by Yveh

代码:

#include<cstdio>
#include<iostream>
#define M 200004
using namespace std;
int cnt[M],w[M],sa[M],rank[M],height[M],tmp[M];
void SA(int len,int up)
{
int *rk=rank,p=0,*id=height,*t=tmp,d=1;
for (int i=0;i<up;i++) cnt[i]=0;
for (int i=0;i<len;i++) cnt[rk[i]=w[i]]++;
for (int i=1;i<up;i++) cnt[i]+=cnt[i-1];
for (int i=len-1;i>=0;i--) sa[--cnt[rk[i]]]=i;
for (;;)
{
for (int i=len-d;i<len;i++) id[p++]=i;
for (int i=0;i<len;i++)
if (sa[i]>=d) id[p++]=sa[i]-d;
for (int i=0;i<up;i++) cnt[i]=0;
for (int i=0;i<len;i++) cnt[t[i]=rk[id[i]]]++;
for (int i=0;i<up;i++) cnt[i]+=cnt[i-1];
for (int i=len-1;i>=0;i--) sa[--cnt[t[i]]]=id[i];
swap(t,rk);
p=1;
rk[sa[0]]=0;
for (int i=0;i<len-1;i++)
if (sa[i]+d<len&&sa[i+1]+d<len&&t[sa[i]]==t[sa[i+1]]&&t[sa[i]+d]==t[sa[i+1]+d])
rk[sa[i+1]]=p-1;
else rk[sa[i+1]]=p++;
if (p>=len) break;
d<<=1;up=p;p=0;
}
}
void Height(int len)
{
int i,j,k=0;
for(i=1; i<=len; i++)  rank[sa[i]]=i;
for(i=0; i<len; i++)
{
if(k)
k--;
else
k=0;
j=sa[rank[i]-1];
while(w[i+k]==w[j+k])
k++;
height[rank[i]]=k;
}
}
main()
{
int len=0,up=0;
char ch=getchar();
while (ch>'z'||ch<'a') ch=getchar();
while (ch>='a'&&ch<='z') w[len++]=ch-'a'+1,ch=getchar();
while (ch>'z'||ch<'a') ch=getchar();
int pos=len;
w[len++]=28;
while (ch>='a'&&ch<='z') w[len++]=ch-'a'+1,ch=getchar();
w[len]=0;
SA(len+1,30);
Height(len);
int ans=0;
for (int i=1;i<len;i++)
if ((sa[i]<pos)^(sa[i-1]<pos))
ans=max(height[i],ans);
printf("%d\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: