题目描述

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

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

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

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

输入输出样例
输入 #1复制

JSOI07

输出 #1复制

I0O7SJ

说明/提示
对于40%的数据字符串的长度不超过10000。

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

题解:

样例分析:
JSOI07排序后

 07JSOI7JSOI0 I07JSO JSOI07 OI07JS SOI07J

每一个字符串取最后一位:I0O7SJ
既然涉及了字符串的排序,就应该想到后缀数组,我们想想这个题,要求按照字符串的大小对各个排列的字符串进行排序。各个排列的字符串我们完全可以用后缀字符串来表示,再用样例分析:
JSOI07的后缀字符串有:

JS0I07
SOI07
Oi07
i07
07
7 按照大小排序后:
07
7
i07
JS0I07
Oi07
SOI07

每一列的最后一位为什么没有?别急,因为字符串是一个环状,所以每一列的最后一位也就是第一位的前一位,所以根据第一位向前推就行
答案还是我们要的I0O7SJ
但是真的就这样做没有问题吗?
当s=“bnabn”
我们会发现后缀字符串bn会排在bnabn前面,但是bn对应的是bnbna,应该是小于bnabn的,因为我们用的后缀字符串,导致缺失的串会影响结果,那该怎么办?
有一个小技巧,我们将s变成原来的两倍
s=“bnabn”+“bnabn”=bnabnbnabn
这样的话,我们取s的后缀字符串就会包含所有通过s变化的串,但是同时也会多出一些部分,会影响结果吗?
并不会
我们只需要观察所有sa[i] ≤n的,而对于这一部分,我们在前n位上一定是有序的,后面的一定不会对前n位的顺序造成影响,这也是我们需要的部分

代码:

连续提交三次都未果?洛谷炸了??

#include <bits/stdc++.h>
using namespace std;
char ss[1000005];
int c[1000005],Rank[1000005],K,N,M,SA[1000005],Temp[1000005],a[1000005];
void Build(int x)
{for (int i=0;i<=x;i++)c[i]=0;for (int i=1;i<=N;i++)c[Rank[Temp[i]]]++;for (int i=1;i<=x;i++)c[i]+=c[i-1];for (int i=N;i>=1;i--)SA[c[Rank[Temp[i]]]--]=Temp[i];
}
void BuildSA()
{for (int i=1;i<=N;i++)Rank[i]=a[i],Temp[i]=i;Build(M=300);for (int T=1;T<N;T*=2){int p=0;for (int i=N-T+1;i<=N;i++)Temp[++p]=i;for (int i=1;i<=N;i++)if (SA[i]>T) Temp[++p]=SA[i]-T;Build(M=p);swap(Rank,Temp);Rank[SA[1]]=1;p=1;for (int i=2;i<=N;i++){if (Temp[SA[i]]==Temp[SA[i-1]]&&Temp[SA[i]+T]==Temp[SA[i-1]+T]) Rank[SA[i]]=p;else Rank[SA[i]]=++p;}}
}
int main()
{scanf("%s",ss+1);N=strlen(ss+1);for (int i=1;i<=N;i++)a[i]=ss[i],a[i+N]=a[i],ss[i+N]=ss[i];//把这个字符串复读一遍[误]N*=2;BuildSA();for (int i=1;i<=N;i++)if (SA[i]<=(N/2))cout<<ss[SA[i]+N/2-1];return 0;
}

[JSOI2007]字符加密相关推荐

  1. 【BZOJ1031】[JSOI2007]字符加密Cipher 后缀数组

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

  2. BZOJ1031: [JSOI2007]字符加密Cipher

    1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 7882  Solved: 3425 [Subm ...

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

    为什么我的后缀数组跑得这么慢... 把字符串复制一遍放在最后, 然后跑sa, 扫一遍就行了... --------------------------------------------------- ...

  4. 后缀数组(bzoj 1031: [JSOI2007]字符加密Cipher)

    后缀数组主要功能: 长度为n的字符串总共有n个后缀,求这n个后缀的字典序 实现方法:倍增+基数排序,过程就是下面那张表 求log(n)次rank数组,每次的rank数组都可以通过上次的rank数组得出 ...

  5. [bzoj1031][JSOI2007]字符加密Cipher

    1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec Memory Limit: 162 MB Submit: 4175 Solved: 1694 [Submit ...

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

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

  7. 【BZOJ 1031】[JSOI2007]字符加密Cipher(后缀数组模板)

    [题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1031 [题意] [题解] 后缀数组模板题; 把整个字符串扩大一倍. 即长度乘2 然后搞 ...

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

    题面 题目传送门 解法 后缀数组模板题吧-- 将字符串两倍,然后求一遍sa数组即可 时间复杂度:\(O(n\ log\ n)\) 代码 #include <bits/stdc++.h> # ...

  9. 【洛谷 P4051】 [JSOI2007]字符加密(后缀数组)

    题目链接 两眼题.. 第一眼裸SA 第二眼要复制一倍再跑SA. 一遍过.. #include <cstdio> #include <cstring> #include < ...

最新文章

  1. 如何备份被独占文件?
  2. pytorch已经安装成功了为什么不能使用import_使用auto keras的过程
  3. NOIP2007 count 统计数字
  4. 【PostgreSQL-9.6.3】触发器实例
  5. Eclipse Photon即将发布
  6. AcWing 2058. 笨拙的手指(暴力枚举)
  7. 《转》常用的正则表达式
  8. 如何删除后缀.Tater勒索病毒并解密.tater勒索病毒加密的病毒文件
  9. java html5 上传_Java实现HTML5拖拽文件上传
  10. 7、mysql的redo log、bin log日志
  11. 使用Mailgun WordPress插件增加订户
  12. 又一微信自动化框架wxauto横空出世了!
  13. Hololens连接mysql_学校hololens开发项目:汽车发动机检修混合现实(MR)教学
  14. 快过年了,该买回家的票了,自动抢票之 12306 抢票篇
  15. scrapy 抓取拉钩 ajax
  16. catia刨面命令_Catia查看装配体剖面的操作方法
  17. 用技术致敬每一位妈妈,B站up主用AI还原李焕英老照片动态影像
  18. VRRP——Master选举
  19. oracle怎么取绝对值,Oracle数值处理函数 (绝对值、取整...)
  20. html框架iframe菜鸟,HTML DOM Frame/IFrame frameBorder 属性 | 菜鸟教程

热门文章

  1. 史上最严重的忘拿钥匙事件 | 今日最佳
  2. 明天放假,我放价!一个国庆假期教你学会数学建模
  3. 墨迹天气android,墨迹天气Android产品分析
  4. java 异步读写_Java异步与AIO
  5. js 上下箭头滚动_JS中的this完全讲解,再也不会被this搞晕了
  6. python调用libvirt_通过python获取kvm虚拟机的监控信息(基于libvirt API)
  7. int函数在Oracle,vb中int是什么意思 ?
  8. leetcode450. 删除二叉搜索树中的节点(详解)
  9. leetcode面试题 02.07. 链表相交
  10. c语言 大数相加,c/c++开发分享C语言计算大数相加的方法