[BZOJ]1031 字符加密Cipher(JSOI2007)
持续划水中……
感觉BZOJ上AC人数多的基本都是一些模板题,也就是某些算法的裸题。这些题目mark一下到时候回来复习也是不错的选择。
Description

Input
输入文件包含一行,欲加密的字符串。注意字符串的内容不一定是字母、数字,也可以是符号等。
Output
输出一行,为加密后的字符串。
Sample Input
JSOI07
Sample Output
I0O7SJ
HINT
字符串的长度不超过100000。
Solution
后缀数组裸题嘛,小C觉得没什么可说的。
本质就是一个长度为2n字符串有n个长度为n的子串,将它们排序。
不过在这里小C要好好讲一讲自己对于后缀数组O(nlogn)算法的理解。
虽然一开始小C看这个算法时也是头皮发麻,但是仔细想想代码中的道理也是非常好理解的。
后缀数组核心代码只有9行,其中4行预处理,1行倍增,4行正式处理,而且预处理部分和正式处理部分本质是相同的。
具体参见小C代码后面的注释。
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MN 200005
#define MS 256
using namespace std;
int mp[MN],rk[][MN],sa[][MN];
char c[MN];
int n,bn,K,g; inline int read()
{
int n=,f=; char c=getchar();
while (c<'' || c>'') {if(c=='-')f=-; c=getchar();}
while (c>='' && c<='') {n=n*+c-''; c=getchar();}
return n*f;
} void work(int* SA,int* RK,int* sa,int *rk)
{
register int i;
//正式处理部分:前3行以rk为第一关键字求出SA,后一行无脑求RK。(注意顺序)
for (i=;i<=n;++i) mp[rk[sa[i]]]=i; //不用前缀和,直接根据串x在sa中的排名得到mp[rk[x]]的前缀和。
for (i=n;i;--i) if (sa[i]>K) SA[mp[rk[sa[i]-K]]--]=sa[i]-K;
//对于扩展后长度大于K的后缀x,利用后缀x+K在sa中的排名得到x在SA中的排名。
for (i=n-K+;i<=n;++i) SA[mp[rk[i]]--]=i;
//然后就只剩下扩展后长度小等于K的后缀x,排名一定比大于K的后缀小,所以后处理。
for (i=;i<=n;++i) RK[SA[i]]=RK[SA[i-]]+(rk[SA[i]]!=rk[SA[i-]] || rk[SA[i]+K]!=rk[SA[i-]+K]);
//无脑求RK,注意用到sa。
//为了执行效率的提高,通常在对后缀排序时,如果发现某次扩展后,所有后缀的rk都不相同,即可停止倍增。
} void prework()
{
register int i;
//预处理部分:前3行用基数排序求出sa[0],后1行无脑求rk[0]。
for (i=;i<=n;++i) ++mp[c[i]];
for (i=;i<MS;++i) mp[i]+=mp[i-];
for (i=;i<=n;++i) sa[][mp[c[i]]--]=i;
for (i=;i<=n;++i) rk[][sa[][i]]=rk[][sa[][i-]]+(c[sa[][i]]!=c[sa[][i-]]);
//注意求rk的时候要按照sa的顺序。
//倍增部分:g代表数组滚动,K是扩展前的大小,扩展一次后sa内的后缀长度变为K*2。
for (g=,K=;K<=bn;K<<=,g^=) work(sa[g^],rk[g^],sa[g],rk[g]);
//至于求height数组的话,只要记住height[rk[i]]>=height[rk[i-1]]这个性质就行了。
} int main()
{
register int i;
scanf("%s",c+); n=strlen(c+);
for (i=;i<=n;++i) c[n+i]=c[i];
bn=n; n<<=;
prework(); c[]=c[n];
for (i=;i<=n;++i) if (sa[g][i]<=bn) putchar(c[sa[g][i]-]);
}
Last Word
本来后缀数组是不亚于LCT困扰小C的存在,现在发现理解了就不需要那样死记硬背了。
最后吐槽一下BZOJ上各种病句连篇的题面,在Blog上贴这种东西尴尬癌都要犯了。
[BZOJ]1031 字符加密Cipher(JSOI2007)的更多相关文章
- BZOJ 1031 字符加密
Description 喜欢钻研问题的JS 同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作 ...
- 【BZOJ】【1031】【JSOI2007】字符加密Cipher
后缀数组 当年感觉好神的题现在好像变水了…… 题意其实有点蛋疼……一开始没看懂<_< 将原串复制一遍接在后面,用后缀数组求一下SA,那么SA<n的就是所找到的那n个字符串,然后把它们 ...
- BZOJ 1031 [JSOI2007]字符加密Cipher | 后缀数组模板题
BZOJ 1031 [JSOI2007]字符加密Cipher | 后缀数组模板题 将字符串复制一遍接在原串后面,然后后缀排序即可. #include <cmath> #include &l ...
- BZOJ 1031: [JSOI2007]字符加密Cipher 后缀数组
1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 6014 Solved: 2503[Submit ...
- bzoj 1031: [JSOI2007]字符加密Cipher 後綴數組模板題
1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3157 Solved: 1233[Submit ...
- BZOJ 1031 [JSOI2007]字符加密Cipher 后缀数组教程
1031: [JSOI2007]字符加密Cipher Description 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一 ...
- 1031: [JSOI2007]字符加密Cipher
1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 7338 Solved: 3182[Submit ...
- 后缀数组 1031: [JSOI2007]字符加密Cipher
/*1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4926 Solved: 2020[Submit ...
- [JSOI2007]字符加密Cipher
bzoj 1031:[JSOI2007]字符加密Cipher Time Limit: 10 Sec Memory Limit: 162 MB Description 喜欢钻研问题的JS同学,最近又迷 ...
随机推荐
- css的内容
块级元素和行内元素的区别: 1. 行内元素部不能够设置宽度和高度.行内元素的宽度和高度是标签内容的宽度和高度.块级元素可以设置宽度和高度. 2. 块级元素会独占一行.而行内元素却部能够独占一行,只能和 ...
- 在Vim按了ctrl+s后
在windows我们码代码的时候习惯ctrl+s保存: 但在vim中使用ctrl+s之后终端就没反应了... vim: ctrl+s终止屏幕输出,敲的东西都有效,就是看不见. ctrl+q恢复:
- 【原创】公司各个阶段 CTO 需要做什么?(上篇)
CTO 是企业内技术最高负责人,对企业的发展起到至关重要的作用.但随着公司的不断发展,CTO 的工作重心也会不断变化.只有在正确的阶段做正确的事,才能更好地为公司做出贡献.我是空中金融 CTO ,TG ...
- SpringBoot的HelloWorld 应用及解释
参考链接: Spring Data JPA - Reference Documentation Spring Data JPA--参考文档 中文版 纯洁的微笑:http://www.ityouknow ...
- 新概念英语(1-25)Mrs. Smith's Kitchen
What colour is the electric cooker? Mrs. Smith's Kitchen is small. There is a refrigerator in the ki ...
- linux下查看mysql日志文件的方法
查看mysql日志方法: mysql默认不允许我们查看日志.需要更改一些设置 1 vi 更改配置文件 允许用户查看日志文件 sudo vi /etc/mysql/mysql.conf.d/mysqld ...
- 南京邮电大学java第一次实验报告
实 验 报 告 ( 2017 / 2018学年 第2学期) 课程名称 JAVA语言程序设计 实验名称 Java集成开发环境的安装与使用. Java变量.表达式与控制结构 实验时间 2018 年 4 月 ...
- WPF在在设计模式,使用动态样式
1.问题分析 WPF有时候要用到主题样式,比如颜色主题(红色.黄色之类的)通常是key相同,而value不同,比如会这么写: Background="{DynamicResource Bac ...
- Docker----起步
最近学习了一下的docker相关的东西,下面介绍一下我个人的学习总结和体会.关于docker的详细介绍和优势,在网上随便都可以找得到,就不做介绍了.这个部分的内容比较简单,有Docker基础的朋友可以 ...
- 一篇文章说透Nginx的rewrite模块
rewrite模块即ngx_http_rewrite_module模块,主要功能是改写请求URI,是Nginx默认安装的模块.rewrite模块会根据PCRE正则匹配重写URI,然后发起内部跳转再匹配 ...