您的位置:首页 > Web前端 > JavaScript

bzoj[JSOI2007]字符加密Cipher

2016-11-29 13:58 239 查看
新学后缀数组,打一道模板题。

想法很简单,因为它是一个圈,所以先在后面补n-1个字符,这样就可以得到所有情况。再求出后缀数组。

#include<cstdio>
#include<cstring>
using namespace std;
int Rsort[210000],sa[210000],rank[210000],wsa[210000],wrank[210000];
char ss[210000];
void get_sa(int n,int m)
{
for(int i=1;i<=n;i++)rank[i]=ss[i];

for(int i=0;i<=m;i++)Rsort[i]=0;
for(int i=1;i<=n;i++)Rsort[rank[i]]++;
for(int i=1;i<=m;i++)Rsort[i]+=Rsort[i-1];
for(int i=n;i>=1;i--)sa[Rsort[rank[i]]--]=i;
int ln=1,p;
while(1)
{
int k=0;for(int i=n-ln+1;i<=n;i++)wsa[++k]=i;

4000
for(int i=1;i<=n;i++)if(sa[i]-ln>0)wsa[++k]=sa[i]-ln;
for(int i=1;i<=n;i++)wrank[i]=rank[wsa[i]];

for(int i=0;i<=m;i++)Rsort[i]=0;
for(int i=1;i<=n;i++)Rsort[wrank[i]]++;
for(int i=1;i<=m;i++)Rsort[i]+=Rsort[i-1];
for(int i=n;i>=1;i--)sa[Rsort[wrank[i]]--]=wsa[i];

memcpy(wrank,rank,sizeof(wrank));
p=1;rank[sa[1]]=1;
for(int i=2;i<=n;i++)
{
if(wrank[sa[i]]!=wrank[sa[i-1]]||wrank[sa[i]+ln]!=wrank[sa[i-1]+ln])p++;
rank[sa[i]]=p;
}
if(p==n)break;
m=p;ln*=2;
}
}
int main()
{
int n;
gets(ss+1);n=strlen(ss+1);
for(int i=1;i<n;i++)ss[i+n]=ss[i];
get_sa(2*n-1,256);
for(int i=1;i<=2*n-1;i++)
if(sa[i]<=n)printf("%c",ss[sa[i]+n-1]);
printf("\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: