nq

[BZOJ5417] [NOI2018]你的名字

情到浓时终转凉″ 提交于 2020-03-02 07:55:40
Description 小A 被选为了ION2018 的出题人,他精心准备了一道质量十分高的题目,且已经把除了题目命名以外的工作都做好了。 由于ION 已经举办了很多届,所以在题目命名上也是有规定的,ION 命题手册规定:每年由命题委员会规定一个小写字母字符串,我们称之为那一年的命名串,要求每道题的名字必须是那一年的命名串的一个非空连续子串,且不能和前一年的任何一道题目的名字相同。 由于一些特殊的原因,小A 不知道ION2017 每道题的名字,但是他通过一些特殊手段得到了ION2017 的命名串,现在小A 有Q 次询问:每次给定ION2017 的命名串和ION2018 的命名串,求有几种题目的命名,使得这个名字一定满足命题委员会的规定,即是ION2018 的命名串的一个非空连续子串且一定不会和ION2017 的任何一道题目的名字相同。 由于一些特殊原因,所有询问给出的ION2017 的命名串都是某个串的连续子串,详细可见输入格式。 Input 第一行一个字符串S ,之后询问给出的ION2017 的命名串都是S 的连续子串。 第二行一个正整数Q,表示询问次数。 接下来Q 行,每行有一个字符串T 和两个正整数l,r,表示询问如果ION2017 的 命名串是S [l..r],ION2018 的命名串是T 的话,有几种命名方式一定满足规定。 Output 输出Q 行,第i

「NOI2018」你的名字

二次信任 提交于 2020-03-02 07:55:16
「NOI2018」你的名字 题目描述 小A 被选为了 \(ION2018\) 的出题人,他精心准备了一道质量十分高的题目,且已经 把除了题目命名以外的工作都做好了。 由于 \(ION\) 已经举办了很多届,所以在题目命名上也是有规定的, \(ION\) 命题手册规 定:每年由命题委员会规定一个小写字母字符串,我们称之为那一年的命名串,要求每道题的名字必须是那一年的命名串的一个非空连续子串,且不能和前一年的任何一道题目的名字相同。 由于一些特殊的原因,小A 不知道 \(ION2017\) 每道题的名字,但是他通过一些特殊 手段得到了 \(ION2017\) 的命名串,现在小A 有 \(Q\) 次询问:每次给定 \(ION2017\) 的命名串和 \(ION2018\) 的命名串,求有几种题目的命名,使得这个名字一定满足命题委员会的规定,即是 \(ION2018\) 的命名串的一个非空连续子串且一定不会和 \(ION2017\) 的任何一道题目的名字相同。 由于一些特殊原因,所有询问给出的 \(ION2017\) 的命名串都是某个串的连续子串, 详细可见输入格式。 输入格式: 第一行一个字符串 \(S\) ,之后询问给出的 \(ION2017\) 的命名串都是 \(S\) 的连续子串。 第二行一个正整数 \(Q\) ,表示询问次数。 接下来 \(Q\) 行,每行有一个字符串 \(T\)

[HAOI2016]找相同字符

∥☆過路亽.° 提交于 2020-02-06 05:17:36
一、题目 点此看题 二、解法 一般这种题都是在第一个字符串上建后缀自动机,然后第二个去乱搞。 我们先处理出每个节点的 r i g h t right r i g h t 集合大小 s i z siz s i z ,然后把第二个串丢进去匹配,设匹配到的点为 p p p ,长度为 l e n len l e n ,则匹配到这个点的贡献为: ( l e n − l e n [ f a [ p ] ] ) × s i z [ p ] (len-len[fa[p]])\times siz[p] ( l e n − l e n [ f a [ p ] ] ) × s i z [ p ] 匹配完之后还要以自动机上的节点再算一遍贡献(因为匹配时我们只算了下面的,没有算上面的),我们再匹配时对 p p p 点打标记,设 s u m [ i ] sum[i] s u m [ i ] 为 i i i 子树内的标记个数(不包含 i i i ),那么这个点的贡献为: s u m [ i ] × ( l e n [ i ] − l e n [ f a [ i ] ] ) × s i z [ i ] sum[i]\times(len[i]-len[fa[i]])\times siz[i] s u m [ i ] × ( l e n [ i ] − l e n [ f a [ i ] ] ) × s i z [

后缀自动机感性理解

心不动则不痛 提交于 2019-12-08 09:39:24
后缀自动机感性理解 后缀自动机实是不是很好理解, 尤其是直接看大段的证明, 不知道它在干什么, 可能会有点懵 那我先介绍一下我的感性理解好了, 大家看这篇文章可能会更好的理解其他人的博客QAQ 前置芝士 : trie树 先来讲一下假后缀树($ n^2 $) , 由于它是假的所以很容易理解, 不用怕 偷图.jpg 对于一个字符串(例: \(bananas\) )来说, 把它的所有后缀($bananas, ananas, nanas, anas, nas, as, s \() 一个一个的插入trie树, 并在末尾打上end标记, 就是暴力的后缀\) trie \(了, 显然时空复杂度均为\) O(n^2)$ 那么可以说后缀自动机是对它很大程度上的优化了, 也就是对重复出现的子串和后缀进行压缩等操作, 使时空复杂度骤降为 \(O(n)\) , 并具有后缀树的一些性质 关于子串的理解: 对于字符串S的一个子串, 你可以理解它为((S的一个后缀)的前缀), 没毛病 也就是如果S的一个子串在trie上一定是一条从根节点开始的路径 有啥用呢 找一个子串的出现次数: 在trie上找到它的路径, 在它下方的end标记之和, 也就是它是多少个后缀的前缀 找一个子串第一次(最后一次)出现位置, 同上, 就是向下走到深度最大(深度最小)的end标记 统计本质不同子串的个数, 即trie树上节点的个数

BASIC合集

戏子无情 提交于 2019-11-30 21:44:05
握手包 给你握手包,flag是Flag_is_here这个AP的密码,自己看着办吧。 提交格式:flag{WIFI密码} 破解wifi密码 丢到kali,用aircrack-ng kali有一个包含常用的WPA的常用密码的字典,我们先解压 -W 后面跟着指定的字典进行爆破 得到wifi密码 flag{11223344} -.-字符串 请选手观察以下密文并转换成flag形式 ..-. .-.. .- --. ..... ..--- ..--- ----- .---- ---.. -.. -.... -.... ..... ...-- ---.. --... -.. .---- -.. .- ----. ...-- .---- ---.. .---- ..--- -... --... --... --... -.... ...-- ....- .---- ----- flag形式为32位大写md5 在线解密 http://www.twinsenliang.net/skill/20070702.html 522018D665387D1DA931812B77763410 A Piece Of Cake nit yqmg mqrqn bxw mtjtm nq rqni fiklvbxu mqrqnl xwg dvmnzxu lqjnyxmt xatwnl, rzn nit uxnntm

SPOJ7258 SUBLEX - Lexicographical Substring Search(后缀自动机)

試著忘記壹切 提交于 2019-11-29 04:22:51
最近学了SAM已经SAM的比较简单的应用,SAM确实不好理解呀,记录一下。 这里提一下后缀自动机比较重要的性质: 1,SAM的点数和边数都是O(n)级别的,但是空间开两倍。 2,SAM每个结点代表一个endpos,每个endpos有可能代表多个字串(当然这些字串的endpos相等),且这些字串的长度呈一个梯形。 3,令tree[x].len为点x代表的所有字串中长度最长的,tree[x].short为最短的,那么tree[x].short=(tree[fa].len)+1,根据这条性质其实tree[x].short就不用算了可以直接由fa得到。 4,SAM的一条边代表往后添加一个字符,且路径和字串一一对应,那么就得到 路径数等于字串数 。 5,在parent树上,x的endpos大小等于x的所有儿子y的endpos大小+1,那么就可以通过建树之后一次dfs计算所有点的endpos大小。 6,第2点说明每个状态endpos 代表的长度区间为 l e n [ f a [ s ] ]-> l e n [ s ] ],那么要求所有本质不同的串的个数就是 ∑ t l e n [ t ] − l e n [ f a [ t ] ] 。 模板题: 洛谷P3804 题目要求出现次数不为1(即endpos大小不为1)的时候计算出现次数*字串大小最大。首先肯定要计算endpos大小

后缀自动机

爱⌒轻易说出口 提交于 2019-11-26 17:00:02
后缀自动机是一个很复杂的算法,下面讲一讲建图和应用。 建图 首先要明确后缀自动机上点和含义:一个点代表的是一类有相同后缀的字符串,而每一个点的fail一定是它本身的后缀。 那么我们定义如下结构体: struct point { int len; int fa; int ch[30]; }; point a[MAXN]; 其中fa就是fail,ch表示点的出边(a~z),len就表示这个点能表示的最大后缀长度。 然后对于一个字符串,我们每次加入一个点。 设当前点为np,之前的主干上的最后一个点为p,当前加入的字符为c。 显然,a[np].len=a[p].len+1(因为从a[p].len出来加上一个c字符就到了np)。 接着我们就要求fail,这一个要分类讨论。 我们从np开始跳fail链,要保证跳到的点的没有c出边,对于这些点,我们把它的c出边设为np。 然后如果直接跳到了1都还没有发现一个有c出边的点,那么就把a[np].fail设为1(这个是case1)。 如果找到了一个有c出边的点,设它的出边连向q,那么就判断一下a[q].len==a[p].len+1(注意此时p是那个有c出边的点)。 如果相等,那么a[np].fa=q,这一个是没问题的了(case2)。 否则我们还要新建一个nq,使a[nq].len=a[p].len+1,然后把q的出边信息全部赋给nq。接下来,a