Problem Specification | Value |
---|---|
Time Limit | 10 Sec |
Memory Limit | 162 MB |
Submit | 5650 |
Solved | 2354 |
Description
喜欢钻研问题的 JS 同学, 最近又迷上了对加密方法的思考. 一天, 他突然想出了一种他认为是终极的加密办法: 把需要加密的信息排成一圈, 显然, 它们有很多种不同的读法. 例如下图, 可以读作:
JSOI07 SOI07J OI07JS I07JSO 07JSOI 7JSOI0 把它们按照字符串的大小排序: 07JSOI 7JSOI0 I07JSO JSOI07OI07JS SOI07J 读出最后一列字符: I0O7SJ, 就是加密后的字符串 (其实这个加密手段实在很容易破解, 鉴于这是突然想出来的, 那就^^). 但是, 如果想加密的字符串实在太长, 你能写一个程序完成这个任务吗?
Input
输入文件包含一行, 欲加密的字符串. 注意字符串的内容不一定是字母、数字, 也可以是符号等.
Output
输出一行, 为加密后的字符串.
Sample Input
JSOI07
Sample Output
I0O7SJ
HINT
对于 100% 的数据字符串的长度不超过 100000.
Source
后缀数组
话说我用的倍增把 x2 写成了++结果爆 TLE 调了很久很久才发现问题~
注意字符串的内容不一定是字母、数字, 也可以是符号等.
注意字符串的内容不一定是字母、数字, 也可以是符号等.
注意字符串的内容不一定是字母、数字, 也可以是符号等.
重要的事情说三遍!! !
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 800100;
#define For(_x,_y,_z) for(int _x=_y;_x<=_z;_x++)
#define ForR(_x,_y,_z) for(int _x=_y;_x>=_z;_x--)
#define Clear(_x) memset(_x,0,sizeof(_x))
// This suffix array is only used to be sorted.
class SuffixArray
{
public:
int n, pwn, rank[maxn], prank[maxn];
int stra[maxn], strb[maxn], srta[maxn], srtb[maxn];
int posa[maxn], posb[maxn], cnt[maxn];
void init(int _n, int* arr)
{
n = _n;
pwn = 1; while (pwn < n) pwn <<= 1;
for (int i = 1; i <= n; i++)
rank[i] = arr[i];
for (int i = n + 1; i <= pwn; i++)
rank[i] = 0;
swap(n, pwn);
return ;
}
void build(void)
{
int c = max(n, 257);
for (int d = 1; d <= n; d <<= 1) {
// Initialize "string" to be compared...
For (i, 1, n) stra[i] = rank[i],
strb[i] = rank[i + d];
// Resetting counter for bit-2 to be sorted
Clear(cnt);
For (i, 1, n) cnt[strb[i]]++;
For (i, 1, c) cnt[i] += cnt[i - 1];
// To sort according to second position
For (i, 1, n) srta[cnt[strb[i]]] = stra[i],
srtb[cnt[strb[i]]] = strb[i],
posb[cnt[strb[i]]--] = i;
// Resetting counter for bit-1 to be sorted
Clear(cnt);
For (i, 1, n) cnt[srta[i]]++;
For (i, 1, c) cnt[i] += cnt[i - 1];
ForR (i, n, 1) stra[cnt[srta[i]]] = srta[i],
strb[cnt[srta[i]]] = srtb[i],
posa[cnt[srta[i]]--] = posb[i];
// Re-updating rank array and continue
For (i, 1, n) rank[posa[i]] = stra[i] == stra[i - 1] && strb[i] == strb[i - 1]
? rank[posa[i - 1]] : rank[posa[i - 1]] + 1;
continue;
}
swap(n, pwn);
// Reverse rank[] to be assigned / positioned easily.
for (int i = 1; i <= n; i++)
prank[rank[i]] = i;
return ;
}
} sa;
int n, arr[maxn];
char str[maxn], res[maxn];
void download(void)
{
// To retrieve the sorting procedures and send to output pipeline.
int pos = 0;
for (int i = 1; i <= 2 * n; i++) {
if (sa.prank[i] > n)
continue;
// Assign result position's value
res[++pos] = arr[sa.prank[i] + n - 1];
}
return ;
}
int main(int argc, char** argv)
{
scanf("%s", str);
n = strlen(str);
For (i, 1, n) arr[i + n] = arr[i] = (int)str[i - 1];
// Done copying... now suffix sorting.
sa.init(n * 2, arr);
sa.build();
// Downloading final results and output...
download();
for (int i = 1; i <= n; i++)
printf("%c", (char)res[i]);
return 0;
}
from pydatagen import *
s_t = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`~!@#$%^&*()-=_+[]|\\:;"\',.<>?/'
s = list()
for i in s_t:
s.append(i)
n = randrange(10, 100000)
r_l = randlist(n, s)
r = str()
for i in r_l:
r = r + i
printf('%s\n' % r)
fclose()