[JSOI2007]字符加密
这个题我们只需要把字符串复制一下,然后求出个SA,输出,就好了。。。
呆码:
#include<iostream> #include<cstdio> #include<cstring> #define N 200010 using namespace std; int n,m,num[N],rk[N],sa[N],se[N]; char ch[N]; inline void rsort() { for(int i=0;i<=m;i++) num[i]=0; for(int i=1;i<=n;i++) num[rk[i]]++; for(int i=1;i<=m;i++) num[i]+=num[i-1]; for(int i=n;i>=1;i--) sa[ num[ rk[ se[i]]]--]=se[i]; } inline void SA() { rsort(); for(int k=1,tot=1; tot<n; m=tot,k<<=1) { tot=0; for(int i=1;i<=k;i++) se[++tot]=n-k+i; for(int i=1;i<=n;i++) if(sa[i]>k) se[++tot]=sa[i]-k; rsort(); swap(rk,se); rk[sa[1]]=tot=1; for(int i=2;i<=n;i++) if(se[sa[i-1]]==se[sa[i]] && se[sa[i]+k]==se[sa[i-1]+k]) rk[sa[i]]=tot; else rk[sa[i]]=++tot; } } int main() { scanf("%s",ch+1); n=strlen(ch+1); m=127; for(int i=1;i<=n;i++) { rk[i]=(int)ch[i]; se[i]=i; } for(int i=n+1;i<=n*2;i++) rk[i]=rk[i-n],se[i]=i,ch[i]=ch[i-n]; n*=2; SA(); for(int i=1;i<=n;i++) if(sa[i]<=n/2) printf("%c",ch[sa[i]+n/2-1]); return 0; }