bzoj1031 [JSOI2007]字符加密Cipher
1031: [JSOI2007]字符加密Cipher
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4351 Solved: 1781
[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。
Source
题意:题意明显
分析:这显然是后缀数组的经典题,关于后缀数组等字符串处理方法我想写一个专题,日后再放链接
上后缀数组代码
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <iostream> 9 #include <algorithm> 10 #include <map> 11 #include <set> 12 #include <ctime> 13 using namespace std; 14 typedef long long LL; 15 typedef double DB; 16 #define For(i, s, t) for(int i = (s); i <= (t); i++) 17 #define Ford(i, s, t) for(int i = (s); i >= (t); i--) 18 #define Rep(i, t) for(int i = (0); i < (t); i++) 19 #define Repn(i, t) for(int i = ((t)-1); i >= (0); i--) 20 #define rep(i, x, t) for(int i = (x); i < (t); i++) 21 #define MIT (2147483647) 22 #define INF (1000000001) 23 #define MLL (1000000000000000001LL) 24 #define sz(x) ((int) (x).size()) 25 #define clr(x, y) memset(x, y, sizeof(x)) 26 #define puf push_front 27 #define pub push_back 28 #define pof pop_front 29 #define pob pop_back 30 #define ft first 31 #define sd second 32 #define mk make_pair 33 inline void SetIO(string Name) { 34 string Input = Name+".in", 35 Output = Name+".out"; 36 freopen(Input.c_str(), "r", stdin), 37 freopen(Output.c_str(), "w", stdout); 38 } 39 40 const int N = 100010; 41 int T1[N*2], T2[N*2], *Ra = T1, *Rs = T2, Sa[N*2], w[N*2]; 42 char Dat[N*2]; 43 int n; 44 45 inline void Input() { 46 gets(Dat+1); 47 } 48 49 inline void Sort(int m) { 50 For(i, 0, m) w[i] = 0; 51 For(i, 1, n) w[Ra[Rs[i]]]++; 52 For(i, 1, m) w[i] += w[i-1]; 53 Ford(i, n, 1) Sa[w[Ra[Rs[i]]]--] = Rs[i]; 54 } 55 56 inline bool Check(int x, int y, int l) { 57 return Rs[x] != Rs[y] || Rs[x+l] != Rs[y+l]; 58 } 59 60 inline void Build() { 61 int Len = 1, p = 0, m = 128, k; 62 For(i, 1, n) Ra[Rs[i] = i] = Dat[i]; 63 Sort(m); 64 while(p < n) { 65 k = 0; 66 For(i, n-Len+1, n) Rs[++k] = i; 67 For(i, 1, n) 68 if(Sa[i] > Len) Rs[++k] = Sa[i]-Len; 69 Sort(m); 70 swap(Ra, Rs); 71 Ra[Sa[1]] = p = 1; 72 For(i, 2, n) { 73 if(Check(Sa[i], Sa[i-1], Len)) p++; 74 Ra[Sa[i]] = p; 75 } 76 Len <<= 1, m = p; 77 } 78 } 79 80 inline void Solve() { 81 n = strlen(Dat+1); 82 For(i, 1, n) Dat[i+n] = Dat[i]; 83 n <<= 1; 84 Build(); 85 86 For(i, 1, n) 87 if(Sa[i] <= n/2) printf("%c", Dat[Sa[i]+n/2-1]); 88 puts(""); 89 } 90 91 int main() { 92 #ifndef ONLINE_JUDGE 93 SetIO("1031"); 94 #endif 95 Input(); 96 Solve(); 97 return 0; 98 }