P4051 [JSOI2007]字符加密
//Pro:P4051 [JSOI2007]字符加密 //我们将字符串复制一遍贴在后面 //然后对这个新字符串跑后缀数组 //令len=原字串的长度 //求出sa[]来后,对于那些sa[i]>len的串,不要他们 //要不然就存下sa[i]+len-1位置的字符 #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int N=2e5+5; int n,m; char s[N]; int rnk[N],sa[N],tp[N],tax[N]; inline void Qsort() { for(int i=1;i<=m;++i) tax[i]=0; for(int i=1;i<=n;++i) ++tax[rnk[i]]; for(int i=1;i<=m;++i) tax[i]+=tax[i-1]; for(int i=n;i;--i) sa[tax[rnk[tp[i]]]--]=tp[i]; } inline void Suffix_Sort() { m=N-1; for(int i=1;i<=n;++i) rnk[i]=s[i],tp[i]=i; Qsort(); for(int l=1,p=0;p<n;m=p,l<<=1) { p=0; for(int i=n-l+1;i<=n;++i) tp[++p]=i; for(int i=1;i<=n;++i) if(sa[i]>l) tp[++p]=sa[i]-l; Qsort(); swap(tp,rnk); rnk[sa[1]]=p=1; for(int i=2;i<=n;++i) rnk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+l]==tp[sa[i-1]+l])?p:++p; } } int main() { scanf("%s",s+1); n=strlen(s+1); memcpy(s+n+1,s+1,n); n<<=1; Suffix_Sort(); n>>=1; for(int i=1;i<=n*2;++i) if(sa[i]<=n) putchar(s[sa[i]+n-1]); return 0; }