1031: [JSOI2007]字符加密Cipher

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 7338  Solved: 3182
[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。

/*
* @Author: lyuc
* @Date: 2017-08-14 16:17:23
* @Last Modified by: lyuc
* @Last Modified time: 2017-08-14 16:56:41
*/
/*
题意:汉语题目不解释 思路:将字符串延长成两段,然后排序,按照前n个后缀的排名进行输出
*/
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h> #define LL long long
#define INF 0x3f3f3f3f
#define MAXN 200005 using namespace std; /****************************************后缀数组模板****************************************/
struct SuffixArray
{
char s[MAXN];
int sa[MAXN];//保存着排序后的后缀
int rank[MAXN];//保存着每个后缀的名词
int height[MAXN];//保存着相邻前缀的最长公共子序列的长度
int t1[MAXN],t2[MAXN],c[MAXN],n;
int dmin[MAXN][];
void build_sa(int m)//m为每个后缀后面加的元素,保证在原字符串中不出现
{
int i,*x=t1,*y=t2;
for(i=;i<m;i++) c[i]=;
for(i=;i<n;i++) c[x[i]=s[i]]++;
for(i=;i<m;i++) c[i]+=c[i-];
for(i=n-;i>=;i--) sa[--c[x[i]]]=i;
for(int k=;k<=n;k<<=)
{
int p=;
for(i=n-k;i<n;i++) y[p++]=i;
for(i=;i<n;i++)if(sa[i]>=k) y[p++]=sa[i]-k;
for(i=;i<m;i++) c[i]=;
for(i=;i<n;i++) c[x[y[i]]]++;
for(i=;i<m;i++) c[i]+=c[i-];
for(i=n-;i>=;i--) sa[--c[x[y[i]]]] = y[i];
swap(x,y);
p=,x[sa[]]=;
for(i=;i<n;i++)
x[sa[i]]= y[sa[i]]==y[sa[i-]]&&y[sa[i]+k]==y[sa[i-]+k]? p-:p++;
if(p>=n) break;
m=p;
}
}
void build_height()//n不能等于1,否则出BUG
{
int i,j,k=;
for(i=;i<n;i++)rank[sa[i]]=i;
for(i=;i<n;i++)
{
if(k)k--;
j=sa[rank[i]-];
while(s[i+k]==s[j+k])k++;
height[rank[i]]=k;
}
}
void initMin()
{
for(int i=;i<=n;i++) dmin[i][]=height[i];
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<=n;i++)
dmin[i][j]=min(dmin[i][j-] , dmin[i+(<<(j-))][j-]);
}
int RMQ(int L,int R)//取得范围最小值
{
int k=;
while((<<(k+))<=R-L+)k++;
return min(dmin[L][k] , dmin[R-(<<k)+][k]);
}
int LCP(int i,int j)//求后缀i和j的LCP最长公共前缀
{
int L=rank[i],R=rank[j];
if(L>R) swap(L,R);
L++;//注意这里
return RMQ(L,R);
}
}sa;
/****************************************后缀数组模板****************************************/
struct Node{
int id;
int val;
bool operator < (const Node & other) const{
return val<other.val;
}
}node[MAXN];
int res[MAXN];
int main(){
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%s",sa.s);
int n=strlen(sa.s);
for(int i=n;i<n*;i++){//双倍
sa.s[i]=sa.s[i-n];
}
sa.s[n*]='\0';
sa.n=n*;
//然后进行排序
sa.build_sa();
sa.build_height(); for(int i=;i<n;i++){
node[i].id=i;
node[i].val=sa.rank[i];
} sort(node,node+n);//进行排序 for(int i=;i<n;i++){
res[i]=node[i].id;
} for(int i=;i<n;i++){
printf("%c",sa.s[res[i]+n-]);
}
printf("\n");
return ;
}

1031: [JSOI2007]字符加密Cipher的更多相关文章

  1. BZOJ 1031: [JSOI2007]字符加密Cipher 后缀数组

    1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6014  Solved: 2503[Submit ...

  2. bzoj 1031: [JSOI2007]字符加密Cipher 後綴數組模板題

    1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3157  Solved: 1233[Submit ...

  3. BZOJ 1031 [JSOI2007]字符加密Cipher 后缀数组教程

    1031: [JSOI2007]字符加密Cipher Description 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一 ...

  4. BZOJ 1031 [JSOI2007]字符加密Cipher | 后缀数组模板题

    BZOJ 1031 [JSOI2007]字符加密Cipher | 后缀数组模板题 将字符串复制一遍接在原串后面,然后后缀排序即可. #include <cmath> #include &l ...

  5. 后缀数组 1031: [JSOI2007]字符加密Cipher

    /*1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4926 Solved: 2020[Submit ...

  6. 【BZOJ】1031: [JSOI2007]字符加密Cipher(后缀数组)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1031 很容易想到这就是将字符串复制到自己末尾然后后缀数组搞出sa然后按区间输出即可. 然后换了下模板 ...

  7. 1031: [JSOI2007]字符加密Cipher - BZOJ

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

  8. bzoj 1031 [JSOI2007]字符加密Cipher 后缀数组模板

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

  9. bzoj 1031: [JSOI2007]字符加密Cipher【后缀数组】

    算是SA的裸题了 把串复制一遍接在原串后面,然后求SA,然后按着SA的顺序输出尾字符即可 #include<iostream> #include<cstdio> #includ ...

随机推荐

  1. 尝试在Linux上部署Asp.net Core应用程序

    快两个月没接触.net,倒是天天在用Linux,所以想尝试一下在Linux运行喜欢的.net 应用. 安装CentOS 安装.Net core for Linux 创建Asp.net Core应用程序 ...

  2. oracle sql*plus常用命令

    一.sys用户和system用户Oracle安装会自动的生成sys用户和system用户(1).sys用户是超级用户,具有最高权限,具有sysdba角色,有create database的权限,该用户 ...

  3. css之outline实现圆角效果

    对,你没有看错,outline也可以实现圆角,不过请先读完自然会知道结果: ============================================================== ...

  4. 01.python基础知识_01

    一.编译型语言和解释型语言的区别是什么? 1.编译型语言将源程序全部编译成机器码,并把结果保存为二进制文件.运行时,直接使用编译好的文件即可 2.解释型语言只在执行程序时,才一条一条的解释成机器语言给 ...

  5. C语言 printf 格式化输出函数

    用 法: int printf(const char *format,[argument]); format 参数输出的格式,定义格式为: %[flags][width][.perc] [F|N|h| ...

  6. DIY智能家居——零基础入门篇

    概要 本文主要根据笔者从零开始接触硬件,以小白视角开启IoT探索,根据相关资料DIY一个温湿度传感器.后经过探索发现新大陆--Home Assistant&Homebridge,最终实现了一个 ...

  7. 概率图论PGM的D-Separation(D分离)

    目录[-] 本文大部分来自:http://www.zhujun.me/d-separation-separation-d.html 一.引言 二.三种情况分析 三.总结 四.应用例子 五.参考资料 其 ...

  8. zoj 2022

    分析: 组合数学类型的题目. 正常的话可能会去分解1~N数里面有几个5和2,但是这样的复杂度为O(nlogn). 其实有更巧妙的办法,可以把问题分解成子问题. 可以发现N!末尾的0与1~N中有几个5的 ...

  9. Oracle Database 10g Express Edition系统文件损坏的解决办法

    1.检查错误代码:ora-10010 亦或是ora-10003,上网找响应的解决办法: 异常状态:登陆不上 常用的方法解决 (1)进入Oracle命令行模式 (2)Shutdown immedaite ...

  10. WPF 中的 Pack URI地(资源文件加载)

    参考资源网http://msdn.microsoft.com/zh-cn/library/aa970069.aspx#Absolute_vs_Relative_Pack_URIs 在 Windows ...