bzoj 1031 [JSOI2007]字符加密Cipher

求出来后缀数组的rank就行了,不会可以去看集训队论文。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
char c[];
int rank[],sa[];
int n;
int a[],b[],wb[],wv[],gs[];
bool cmp(int *x,int a,int b,int l)
{
return x[a]==x[b]&&x[a+l]==x[b+l];
}
void da(int *x,int *sa,int n,int m)
{
int i,j,p,*y=wb;
for(i=;i<m;i++)gs[i]=;
for(i=;i<n;i++)gs[x[i]]++;
for(i=;i<m;i++)gs[i]+=gs[i-];
for(i=n-;~i;i--)sa[--gs[x[i]]]=i;
for(j=,p=;p<n;j<<=,m=p)
{
for(i=n-j,p=;i<n;i++)y[p++]=i;
for(i=;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
for(i=;i<n;i++)wv[i]=x[y[i]];
for(i=;i<m;i++)gs[i]=;
for(i=;i<n;i++)gs[wv[i]]++;
for(i=;i<m;i++)gs[i]+=gs[i-];
for(i=n-;~i;i--)sa[--gs[wv[i]]]=y[i];
swap(x,y);x[sa[]]=;p=;
for(i=;i<n;i++)x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
}
int main()
{
scanf("%s",c);
n=strlen(c);
for(int i=n;i<*n;i++)c[i]=c[i-n];
for(int i=;i<n<<;i++)rank[i]=c[i];
da(rank,sa,n*+,);
for(int i=;i<=n*;i++)
{
if(sa[i]+n-<n*-)putchar(c[sa[i]+n-]);
}
return ;
}
上一篇:《从陷阱中学习C/C++》读书笔记


下一篇:MessageBox.Show()如何换行