[BZOJ1031][JSOI2007]字符加密Cipher 解题报告
Description
喜欢钻研问题的JS 同学,最近又迷上了对加密方法的思考。一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法。例如下图,可以读作:
JSOI07 SOI07J OI07JS I07JSO 07JSOI 7JSOI0 把它们按照字符串的大小排序: 07JSOI 7JSOI0 I07JSO JSOI07 OI07JS SOI07J 读出最后一列字符:I0O7SJ,就是加密后的字符串(其实这个加密手段实在很容易破解,鉴于这是突然想出来的,那就^^)。但是,如果想加密的字符串实在太长,你能写一个程序完成这个任务吗?
这道题好像也做了挺久...一个半小时吧
首先题目很亲切 总感觉去年暑假在镇中有过类似的题 但是那道题好像有神奇的O(n)做法
其实问题可以转化为将字符串及其循环以后的n-1个串从小到大排序,然后输出字符串首位的前一位字符
我们要解决字符串及其循环以后一共n个串的排序
我用后缀数组解决
我们可以直接用后缀数组处理出1 << (trunc(ln(n)/ln(2)))长度的排序
将后缀处理成子串的方法就在原串后面再接一次
然后再类似于倍增一点点将剩下的长度加入
实现方法类似于后缀数组 几个细节改动一下
但是由于要用到中间的数据,所以sa和rank数组要在每一次之后保留不能重复利用
还是一道非常不错的题呢^
program bzoj1031;
const maxn=;
var i,x,n:longint;
ss:ansistring;
a,s,tmp,rk,sa2:array[-..maxn]of longint;
rank,sa:array[-..,-..maxn]of longint; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; procedure Suffix_Array;
var i,j,k,p,v0,v00,v01,v1,size:longint;
begin
size:=;
for i:= to n- do rank[,i]:=a[i];
for i:= to size- do s[i]:=;
for i:= to n- do inc(s[rank[,i]]);
for i:= to size- do inc(s[i],s[i-]);
for i:=n- downto do
begin
dec(s[rank[,i]]);
sa[,s[rank[,i]]]:=i;
end;
j:=;k:=;
size:=n;
while j<=n >> do
begin
p:=;
for i:=n-j to n- do
begin
tmp[p]:=i;
inc(p);
end;
for i:= to n- do if sa[k-,i]-j>= then
begin
tmp[p]:=sa[k-,i]-j;
inc(p);
end;
for i:= to size- do s[i]:=;
for i:= to n- do inc(s[rank[k-,i]]);
for i:= to size- do inc(s[i],s[i-]);
for i:=n- downto do
begin
dec(s[rank[k-,tmp[i]]]);
sa[k,s[rank[k-,tmp[i]]]]:=tmp[i];
end;
p:=;rank[k,sa[k,]]:=;
for i:= to n- do
begin
v0:=sa[k,i-];v1:=sa[k,i];
if v0+j<n then v00:=rank[k-,v0+j] else v00:=-;
if v1+j<n then v01:=rank[k-,v1+j] else v01:=-;
if (rank[k-,v0]=rank[k-,v1])and(v00=v01) then rank[k,sa[k,i]]:=p else
begin
inc(p);
rank[k,sa[k,i]]:=p; end;
end;
j:=j << ;inc(k);
end;
end; procedure solve;
var i,j,k,p,x,rec,v0,v1,v00,v01,size:longint;
begin
x:=trunc(ln(n >> )/ln());
size:=max(,n);
for i:= to n- do rk[i]:=rank[x,i];
for i:= to size- do s[i]:=;
for i:= to n- do inc(s[rk[i]]);
for i:= to size- do inc(s[i],s[i-]);
for i:=n- downto do
begin
dec(s[rk[i]]);
sa2[s[rk[i]]]:=i;
end;
rec:=n >> - << x;
while rec<> do
begin
x:=trunc(ln(rec)/ln());
p:=;
for i:=n- << x to n- do
begin
tmp[p]:=i;
inc(p);
end;
for i:= to n- do if sa[x,i]- << x>= then
begin
tmp[p]:=sa[x,i]- << x;
inc(p);
end;
for i:= to size- do s[i]:=;
for i:= to n- do inc(s[rk[i]]);
for i:= to size- do inc(s[i],s[i-]);
for i:= to n- do
begin
dec(s[rk[tmp[i]]]);
sa2[s[rk[tmp[i]]]]:=tmp[i];
end;
p:=;tmp[sa2[]]:=;
for i:= to n- do
begin
v0:=sa2[i-];v1:=sa2[i];
if v0+ << x<n then v00:=rank[x,v0+ << x] else v00:=-;
if v1+ << x<n then v01:=rank[x,v1+ << x] else v01:=-;
if (rk[v0]=rk[v1])and(v00=v01) then tmp[sa2[i]]:=p else
begin
inc(p);
tmp[sa2[i]]:=p;
end;
end;
for i:= to n- do rk[i]:=tmp[i];
dec(rec, << x);
end;
end; begin
readln(ss);n:=length(ss);
for i:= to n- do a[i]:=ord(ss[i+]);
for i:=n to *n- do a[i]:=a[i-n];
n:=n*;
Suffix_Array;
solve;
for i:= to n- do if sa2[i]<(n >> ) then
begin
x:=sa2[i]-;
if x=- then x:=n >> -;
write(ss[x+]);
end;
end.
[BZOJ1031][JSOI2007]字符加密Cipher 解题报告的更多相关文章
- [BZOJ1031] [JSOI2007] 字符加密Cipher (后缀数组)
Description 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法 :把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作 ...
- [bzoj1031][JSOI2007]字符加密Cipher——后缀数组
Brief Description 给定一个长度为n的字符串,你需要对其进行加密. 把字符串围成一个环 显然从任意一个位置开始都可以有一个长度为n的串 把产生的n个串按字典序排序,把这n个串的最后一个 ...
- BZOJ1031: [JSOI2007]字符加密Cipher
传送门 后缀数组模板题 //BZOJ 1031 //by Cydiater //2016.9.21 #include <iostream> #include <cstring> ...
- [BZOJ1031][JSOI2007]字符加密Cipher(后缀数组)
传送门 算是个模板. 题目说循环,那就再复制一串拼接上. 然后求后缀数组,再搞就可以. 虽然是求后缀,会在后面多一些字符串,然而题目中说的是循环一圈,但是没有影响. ——代码 #include < ...
- 【BZOJ1031】[JSOI2007]字符加密Cipher 后缀数组
[BZOJ1031][JSOI2007]字符加密Cipher Description 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法 :把需要加密的 ...
- BZOJ 1031: [JSOI2007]字符加密Cipher 后缀数组
1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 6014 Solved: 2503[Submit ...
- 【BZOJ-1031】字符加密Cipher 后缀数组
1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5504 Solved: 2277[Submit ...
- bzoj 1031: [JSOI2007]字符加密Cipher 後綴數組模板題
1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3157 Solved: 1233[Submit ...
- 1031: [JSOI2007]字符加密Cipher
1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 7338 Solved: 3182[Submit ...
随机推荐
- MQTT 开源代理mosquitto的网络层封装相当sucks
最近学习MQTT协议,选择了当前比较流行的MQTT Broker “mosquitto”,但是在阅读代码过程中发现其网络底层库封装的相当差劲. 对于MQTT协议的变长头长度的读取上,基本上采取每次一个 ...
- 「暑期训练」「基础DP」 Common Subsequence (POJ-1458)
题意与分析 很简单:求最长公共子序列. 注意子序列与子串的差别:一个不连续一个连续.一份比较好的参考资料见:https://segmentfault.com/a/1190000002641054 状态 ...
- 【java并发编程实战】第六章:线程池
1.线程池 众所周知创建大量线程时代价是非常大的: - 线程的生命周期开销非常大:创建需要时间,导致延迟处理请求,jvm需要分配空间. - 资源消耗:线程需要占用空间,如果线程数大于可用的处理器数量, ...
- 一款代码高亮插件 -- SyntaxHighlighter
SyntaxHighlighter 是当前用得最多的一款代码高亮插件,包括本博客也用到了该插件来显示代码,大家可以看到效果了.只不过这是针对WordPress的一款代码高亮插件,而今天我要给大家介绍的 ...
- 稳定匹配 - Stable Matching
这篇文章将会对稳定匹配算法进行介绍及Python代码的实现,第一部分会针对稳定匹配的Gale-Shapley算法进行解析,第二部分就是用Python对该算法进行实现. 一.稳定匹配算法原理 1.1 介 ...
- linux备忘录-系统服务daemon
服务(daemon)及其分类 Linux中的服务被称为daemon(daemon是守护神,恶鬼的意思哦).这些daemon会常驻在内存当中,从而对我们的系统和任务等进行一些辅助性的工作.实际上,dae ...
- BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)
题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一 ...
- 数据结构14——AC自动机
一.相关介绍 知识要求 字典树Trie KMP算法 AC自动机 多模式串的字符匹配算法(KMP是单模式串的字符匹配算法) 单模式串问题&多模式串问题 单模就是给你一个模式串,问你这个模式串是否 ...
- WCF身份验证三:自定义身份验证之<MessageHeader>
关于使用SoadHeader验证Robin已经有一篇十分精彩的文章: WCF进阶:为每个操作附加身份信息, 不过我的思维方式总是跟别人有点不太一样, 还是把类似的内容用我的方式重新组织一下. 使用He ...
- Hibernate基本演示
保存一个对象到数据库中 目录结构 hibernate.cfg.xml <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hi ...
