解密

来源:互联网 发布:滨州市安全网络平台 编辑:程序博客网 时间:2024/04/29 16:33

题意

Mirko要解一段加密文,但他只知道某一个句子是原文的一部分。你的任务是要在密文中找到第一个对应这个句子的地方。
文段是通过用某个单词(可能和原文一样的单词)替换原始文段每一个单词来加密的。如果某些单词在原文出现一次以上,就会使用相同的替换单词来替换。没有两个不同的单词使用相同的替换单词。
单词是通过空格隔开的小写字母序列。句子是连续单词的序列。

文段、句子长度不超过106
Time Limits:2000ms
Memory Limits:64M

分析

我们发现,如果一段密文是由原文加密而来的,那该段密文中每两个相同单词间的间距要与原文中每两个相同单词间的间距相同。我们可用f[i]表示原文句子的第i个单词与它后面距离为f[i]的单词相同。这样得出一个新的数组(可以看成一个新的字符串),然后对于密文做同样的处理。若一段密文满足条件,则该段密文的新字符串要与原文的新字符串相同。
问题到这里就比较显然了,我们可以用哈希求出原文新字符串对应的哈希值,然后动态维护一段长度与原文长度相同的密文字符串的哈希值。即从左往右扫原文,每将我们将当前枚举的那段密文串向右移一位,就减去原来最左边的密文串的f[l1]对哈希值的影响,再加上当前新结尾的f[r]对哈希值的影响。然后再将当前哈希值与目标哈希值比较。
但这样我们又会发现一个问题,就是如果密文串中的一个f[i]+i指向的位置超过了当前枚举的密文串的结尾,那么这个f[i]应暂时为0,当结尾扫到f[i]+i时再将它加进去(若此时i已不在枚举的密文串内略过)。所以我们可以用一个数组记录这个单词前面的与它最近的相同的单词的位置,当新扫到一个位置时用该数组值更新哈希值。

0 0
原创粉丝点击