码迷,mamicode.com
首页 > 编程语言 > 详细

[BZOJ1031][JSOI2007]字符加密Cipher 后缀数组

时间:2017-07-19 14:33:32      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:gif   std   输入   strlen   space   alt   bcf   UI   splay   

1031: [JSOI2007]字符加密Cipher

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 7248  Solved: 3138
[Submit][Status][Discuss]

Description

  喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考。一天,他突然想出了一种他认为是终极的加密办法
:把需要加密的信息排成一圈,显然,它们有很多种不同的读法。例如下图,可以读作:

 技术分享

JSOI07 SOI07J OI07JS I07JSO 07JSOI 7JSOI0把它们按照字符串的大小排序:07JSOI 7JSOI0 I07JSO JSOI07
 OI07JS SOI07J读出最后一列字符:I0O7SJ,就是加密后的字符串(其实这个加密手段实在很容易破解,鉴于这是
突然想出来的,那就^^)。但是,如果想加密的字符串实在太长,你能写一个程序完成这个任务吗?

Input

  输入文件包含一行,欲加密的字符串。注意字符串的内容不一定是字母、数字,也可以是符号等。

Output

  输出一行,为加密后的字符串。

Sample Input

JSOI07

Sample Output

I0O7SJ

HINT

 

对于100%的数据字符串的长度不超过100000。

 
 
裸的模板题,不解释
代码:
技术分享
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 using namespace std;
 8 int sa[202020],rank[202020],rank1[202020],a[202020];
 9 int c[202020];
10 int m=0;
11 char ch[202020];
12 int n=0;
13 void build_sa()
14 {
15     memset(c,0,sizeof(c));
16     int *x=rank,*y=rank1;
17     for(int i=0;i<n;i++) c[x[i]=ch[i]]++;
18     for(int i=1;i<m;i++) c[i]+=c[i-1];
19     for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
20     for(int i=1;i<=n;i<<=1)
21     {
22         int p=0;
23         for(int j=n-i;j<n;j++) y[p++]=j;
24         for(int j=0;j<n;j++) if(sa[j]-i>=0) y[p++]=sa[j]-i;
25         memset(c,0,sizeof(c));
26         for(int j=0;j<n;j++) c[x[y[j]]]++;
27         for(int j=1;j<m;j++) c[j]+=c[j-1];
28         for(int j=n-1;j>=0;j--) sa[--c[x[y[j]]]]=y[j];
29         swap(x,y);
30         p=1;x[sa[0]]=0;
31         for(int j=1;j<n;j++) x[sa[j]]=y[sa[j-1]]==y[sa[j]]&&y[sa[j]+i]==y[sa[j-1]+i]? p-1:p++;
32         if(p>=n) break;
33         m=p;
34     }
35 }
36 int main()
37 {
38     int len=0;
39     scanf("%s",ch);
40     len=strlen(ch);
41     for(int i=0;i<len-1;i++) ch[i+len]=ch[i];
42     for(int i=0;i<len;i++) m=max(m,int(ch[i]));
43     n=len*2-1;
44     m++;
45     build_sa();
46     for(int i=0;i<n;i++)
47         if(sa[i]<len) printf("%c",ch[sa[i]+len-1]);
48 }
View Code

 

[BZOJ1031][JSOI2007]字符加密Cipher 后缀数组

标签:gif   std   输入   strlen   space   alt   bcf   UI   splay   

原文地址:http://www.cnblogs.com/wls001/p/7204782.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!