bzoj 1031[JSOI2007]字符加密 - 后缀数组

Posted 大财主

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1031[JSOI2007]字符加密 - 后缀数组相关的知识,希望对你有一定的参考价值。

                

1031: [JSOI2007]字符加密Cipher

Time Limit: 10 Sec  Memory Limit: 162 MB

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 <algorithm>
  3 #include <cstring>
  4 #include <cstdio>
  5 #define LL long long
  6 using namespace std;
  7 
  8 const int MAXN = 3e5 + 10;
  9 char str[MAXN];
 10 int m;
 11 int ra[MAXN], tp[MAXN];
 12 int SA[MAXN];
 13 int cur[MAXN];
 14 int c[MAXN];
 15 int len;
 16 int p;
 17 inline LL read()
 18 {
 19     LL x = 0, w = 1; char ch = 0;
 20     while(ch < 0 || ch > 9) {
 21         if(ch == -) {
 22             w = -1;
 23         }
 24         ch = getchar();
 25     }
 26     while(ch >= 0 && ch <= 9) {
 27         x = x * 10 + ch - 0;
 28         ch = getchar();
 29     }
 30     return x * w;
 31 }
 32 
 33 void sort(int m)
 34 {
 35     for(int i = 0; i <= m; i++) {
 36         c[i] = 0;
 37     }
 38     for(int i = 1; i <= len; i++) {
 39         c[ra[tp[i]]]++;
 40     }
 41     for(int i = 1; i <= m; i++) {
 42         c[i] += c[i - 1];
 43     }
 44     for(int i = len; i >= 1; i--) {
 45         SA[c[ra[tp[i]]]--] = tp[i];
 46     }
 47 }
 48 
 49 void copy()
 50 {
 51     for(int i = 1; i <= len; i++) {
 52         cur[i] = ra[i];
 53     }
 54 }
 55 
 56 void suffix()
 57 {
 58     for(int i = 1; i <= len; i++) {
 59         ra[i] = str[i];
 60         tp[i] = i;
 61     } 
 62     sort(m = 128);
 63     for(int w = 1, p = 0; p < len; w += w, m = p) {
 64         p = 0;
 65         for(int j = len - w + 1; j <= len; j++) {
 66             tp[++p] = j;
 67         }
 68         for(int i = 1; i <= len; i++) {
 69             if(SA[i] > w) {
 70                 tp[++p] = SA[i] - w;
 71             }
 72         }
 73         sort(m);
 74         copy();
 75         ra[SA[1]] = p = 1;
 76         for(int i = 2; i <= len; i++) {
 77             if(cur[SA[i]] == cur[SA[i - 1]] && cur[SA[i - 1] + w] == cur[SA[i] + w]) {
 78                 ra[SA[i]] = p; 
 79             } else {
 80                 ra[SA[i]] = ++p;
 81             }
 82         }
 83     }
 84 }
 85 int main()
 86 {
 87     scanf("%s", str + 1);
 88     len = strlen(str + 1);
 89     for(int i = 1; i <= len; i++) {
 90         str[i + len] = str[i];
 91     }
 92     len += len;
 93     suffix();
 94     for(int i = 1; i <= len; i++) {
 95         if(SA[i] <= len / 2) 
 96         cout<<str[SA[i] + len / 2  - 1];
 97     }
 98     cout<<endl;
 99     return 0;
100 }
View Code

 



以上是关于bzoj 1031[JSOI2007]字符加密 - 后缀数组的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1031: [JSOI2007]字符加密Cipher

[Bzoj]1031: [JSOI2007]字符加密Cipher

bzoj 1031: [JSOI2007]字符加密Cipher

[bzoj1031][JSOI2007]字符加密Cipher

bzoj 1031[JSOI2007]字符加密 - 后缀数组

BZOJ 1031[JSOI2007]字符加密Cipher