其实很水的一道题吧.... 题意是:每次给定一个串\(T\)以及\(l, r\),询问有多少个字符串\(s\)满足,\(s\)是\(T\)的子串,但不是\(S[l .. r]\)的子串 统计\(T\)本质不同的串,建个后缀自动机 然后自然的可以想到,对于每个\(T\)的子串,它对应了一个\(right\)集合 那么,它应该会被这个\(right\)集合所限制 考虑对于每个\(i\),求出最小的\(l\)使得\(T[l .. i]\)存在于\(S[l..r]\)中 这个可以套个线段树转移 然后就没…
bzoj5417/luoguP4770 [NOI2018]你的名字(后缀自动机+线段树合并) bzoj Luogu 给出一个字符串 $ S $ 及 $ q $ 次询问,每次询问一个字符串 $ T $ 有多少本质不同的子串不是 $ S[l,r] $ 的子串. 题解时间 跟上一道题有点像哈. 只不过这一次是要将 $ T $ 放在 $ S $ 上匹配. 我们先不管每次选取的 $ S $ 段不同,就假设我们已经建好了选取的 $ S $ 段的SAM(也就是前68pts啦) 我们直接把 $ T $ 放上去匹…
题目链接: [Noi2018]你的名字 题目大意:给出一个字符串$S$及$q$次询问,每次询问一个字符串$T$有多少本质不同的子串不是$S[l,r]$的子串($S[l,r]$表示$S$串的第$l$个字符到第$r$个字符组成的子串). 首先考虑$l=1,r=|S|$的情况,对$T$串建立后缀自动机,可以知道$T$串本质不同的子串个数就是后缀自动机上每个点的$len[i]-len[pre[i]]$($len[i]$代表这个点所能表示的最长串长度),这也就是后缀自动机上每个点贡献的子串个数.对于每个点…
题目描述 小A 被选为了ION2018 的出题人,他精心准备了一道质量十分高的题目,且已经把除了题目命名以外的工作都做好了. 由于ION 已经举办了很多届,所以在题目命名上也是有规定的,ION 命题手册规定:每年由命题委员会规定一个小写字母字符串,我们称之为那一年的命名串,要求每道题的名字必须是那一年的命名串的一个非空连续子串,且不能和前一年的任何一道题目的名字相同. 由于一些特殊的原因,小A 不知道ION2017 每道题的名字,但是他通过一些特殊手段得到了ION2017 的命名串,现在小A 有…
LOJ 洛谷 BZOJ 考虑\(l=1,r=|S|\)的情况: 对\(S\)串建SAM,\(T\)在上面匹配,可以得到每个位置\(i\)的后缀的最长匹配长度\(mx[i]\). 因为要去重,对\(T\)也建SAM,计算上面所有节点的答案.记\(pos[i]\)表示\(i\)节点第一次出现的下标(同一节点代表的串出现的位置集合相同,所以随便记一个即可). 则节点\(i\)的答案为:\(\max(0,\ len[i]-\max(len[fa[i]],\ mx[pos[i]]))\). 考虑\(l,r…
即求b串有多少个本质不同的非空子串,在a串的给定区间内未出现.即使已经8102年并且马上就9102年了,还是要高举SA伟大旗帜不动摇. 考虑离线,将所有询问串及一开始给的串加分隔符连起来,求出SA.对于每个询问,我们对串的每个后缀,求出其在给定区间中最长的lcp是多少.这样就能得到不考虑本质不同时的答案,再考虑该串名次数组中相邻后缀的lcp去一下重即可. 考虑怎么求这个最长的lcp.设该后缀在名次数组中的位置是i,给定区间是[l,r],这个东西实际上就是max{min{lcp(i..j),r-s…
这道题各位大神好像都是用后缀自动机做的?.....蒟蒻就秀秀智商写一写后缀数组解法..... 求出Height数组后, 我们枚举每一位当做子串的开头. 如上图(x, y是height值), Heights数组中相邻的3个后缀, 假如我们枚举s2的第一个字符为开头, 那我们发现, 长度至少为len = max(x, y)+1, 才能满足题意(仅出现一次). 这个很好脑补...因为s2和其他串的LCP是RMQ, 肯定会<=LCP(s1,s2)或<=LCP(s2,s3). 然后就用len去更新s2中…
题目大意 给你一颗trie树,令\(s_i\)为点\(i\)到根的路径上的字符组成的字符串.求\(max_{u\neq v}(LCP(s_u,s_v)+LCS(s_u,s_v))\) \(LCP=\)最长公共前缀,\(LCS=\)最长公共后缀 \(1\leq n\leq 200000\),字符集为\(\{0\ldots 300\}\) 题解 我们先看看这个\(LCP(s_u,s_v)\)怎么求 广义后缀自动机不行.广义后缀树可能可以,但我不会.广义后缀数组可以.然后我就开始手推广义后缀数组 广义…
集训讲字符串的时候我唯一想出正解的题-- 链接 BZOJ 2865 题面 给出一个长度为n (n <= 5e5) 的字符串,对于每一位,求包含该位的.最短的.在原串中只出现过一次的子串. 题解 "只出现过一次",想到后缀数组,后缀数组可以求出以第i位开头的最短的在原串中只出现过一次的子串--它的长度是min(height[rank[i]], height[rank[i] + 1) + 1. 所以我们枚举每个位置i,找到这个串,然后考虑它的贡献: 对于这个串之内的位置,答案可以用这…
根据height数组的定义,和当前后缀串i最长的相同串的长度就是max(height[i],height[i+1]),这个后缀贡献的最短不同串长度就是len=max(height[i],height[i+1]) 考虑这个贡献的范围,对于i~i+len,贡献是len,对于w=i+len+1~n可以更新w-len+1,也就是这长为len的串再向右延伸,可以证明这也是不重子串 这两个东西用两个线段树维护,w-len+1这个直接把-len+1打在线段树上,查询的时候再加回w即可 #include<ios…