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

bzoj1031 [JSOI2007]字符加密Cipher

2017-09-23 07:25 344 查看
题目

算是bzoj上面的后缀数组第一题吧。比较简单。

求出sa数组后输出s[sa[i]+len-1]即可。

抓紧背板啊。。。

#include<bits/stdc++.h>
#define N 500000
using namespace std;
int sa[N+1],tmp1[N+1],tmp2[N+1],c[N+1];
int m,n,len;
char s[N+1];
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
int x=0,b=1;
char c=nc();
for(;!(c<='9'&&c>='0');c=nc())if(c=='-')b=-1;
for(;c<='9'&&c>='0';c=nc())x=x*10+c-'0';
return x*b;
}
inline void write(int x)
{
if(x==0)putchar('0');
else
{
char buf[15];
int len=0;
if(x<0)putchar('-'),x=-x;
while(x)buf[++len]=x%10+'0',x/=10;
for(int i=len;i>=1;i--)putchar(buf[i]);
}
putchar(' ');
}
inline void get_sa(char *ch)
{
int n=strlen(ch),m;
for(int i=0;i<n;i++)m=max((int)ch[i],m);m++;
int p,*x=tmp1,*y=tmp2;
for(int i=0;i<m;i++)c[i]=0;
for(int i=0;i<n;i++)c[x[i]=ch[i]]++;
for(int i=1;i<m;i++)c[i]+=c[i-1];
for(int i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
for(int k=1;k<=n;k<<=1)
{
p=0;
for(int i=n-k;i<n;i++)y[p++]=i;
for(int i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k;
for(int i=0;i<m;i++)c[i]=0;
for(int i=0;i<n;i++)c[x[y[i]]]++;
for(int i=1;i<m;i++)c[i]+=c[i-1];
for(int i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
swap(x,y);
p=1,x[sa[0]]=0;
for(int i=1;i<n;i++)
x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
if(p>=n)break;
m=p;
}
}
int main()
{
freopen("in.txt","r",stdin);
scanf("%s",s);len=strlen(s);
for(int i=0;i<len;i++)s[i+len]=s[i];
get_sa(s);
for(int i=0;i<len*2;i++)
if(sa[i]<len)printf("%c",s[sa[i]+len-1]);
return 0;
}


姿势水平不高,比较慢。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: