讲解在满分做法的博客中 Code: #include <cstdio> #include <algorithm> #include <cstring> #define setIO(s) freopen(s".in","r",stdin) #define maxn 3000008 #define ll long long #define N 30 using namespace std; int pos[maxn],n,querie…
传送门 我有种自己根本没学过SAM的感觉……最后还是抄了老半天的题解…… 首先,对$S$和每一次的$T$都建一个SAM 先考虑一下$l=1,r=\left| S \right|$的情况 设$lim_i$表示字符串$T[1..i]$能在$S$中匹配到的最长后缀(即$T[i-lim_i+1,i]$是$S$的子串且$lim_i$最大)(有可能不存在这个字符那么$lim_i=0$) 这个$lim_i$可以不断地在$S$的后缀自动机上跳来求出.当无法向下匹配时,一直跳parent树直到可以匹配为止 我们假…
看到题目名字去补番是种怎么样的体验 我只会 \(68\) 分,打了个暴力.正解看了一会儿,发现跟 \([HEOI2016/TJOI2016]\) 字符串很像,用线段树合并维护 \(endpos\) 集合,然后一边匹配一边记录答案. \[ans=\sum_{i=1}^{cnt}max(0,len_i-max(len_{fa_i},lim_{pos_i}))\] \(Code\ Below:\) #include <bits/stdc++.h> #define ll long long using…
先考虑l=1,r=n,并且不要求本质不同的情况.对原串建SAM,将询问串在上面跑,得到每个前缀的最长匹配后缀即可得到答案. 然后考虑本质不同.对询问串也建SAM,统计每个节点的贡献,得到该点right集合中任意一个的匹配长度即可. 然后考虑原问题.我们需要求的仍然只是每个前缀的最长匹配后缀.通过线段树合并得到原串SAM每个点的right集合,同样将询问串在上面跑,跑的时候根据所达点right集合在给定区间中的最大值得到该点极限匹配长度,判断是否能在该点匹配(即极限匹配长度是否不小于该点所表示的最…
题目: 洛谷4770 UOJ395 分析: 一个很好的SAM应用题-- 一句话题意:给定一个字符串\(S\).每次询问给定字符串\(T\)和两个整数\(l\).\(r\),求\(T\)有多少个本质不同的非空子串不是\(S[l,r]\)的子串. 首先显然是"正难则反",求有多少个本质不同的非空子串是\(S[l,r]\)的子串(下面的"答案"一词指的是这个值).先考虑没有\(l\)和\(r\)限制的情况.分别处理询问.对于\(S\)建出后缀自动机.枚举\(T\)的所有前…
即求b串有多少个本质不同的非空子串,在a串的给定区间内未出现.即使已经8102年并且马上就9102年了,还是要高举SA伟大旗帜不动摇. 考虑离线,将所有询问串及一开始给的串加分隔符连起来,求出SA.对于每个询问,我们对串的每个后缀,求出其在给定区间中最长的lcp是多少.这样就能得到不考虑本质不同时的答案,再考虑该串名次数组中相邻后缀的lcp去一下重即可. 考虑怎么求这个最长的lcp.设该后缀在名次数组中的位置是i,给定区间是[l,r],这个东西实际上就是max{min{lcp(i..j),r-s…
题面 rt,如果省选没退役就补 SAM的优势:简单明了 先建S的SAM并标记所有节点,之后每次询问直接把T按广义SAM的方法插上去,统计新加的节点到根的状态代表的本质不同子串数,减掉被标记的部分就是T独有的 #include<cstdio> #include<vector> #include<cstring> #include<algorithm> using namespace std; ; ],fth[N],len[N],vis[N],ori[N]; i…
SAM真让人头秃. 题面 https://www.luogu.org/problemnew/show/P4770 首先考虑 l=1,r=∣S∣的做法 如果对于ION2018的子串不用判重的话,对ION2017建SAM跑一遍就好了. 此时ION2018的每一个前缀对答案的贡献为前缀长度-匹配长度. 考虑怎么去重. 这应该算是SAM比较常用去重的一种套路. 对ION2018建出SAM. 原本就算答案的方式是枚举子串的右端点的位置. 现在改为枚举枚举SAM上的节点. 由于对于每种串要只计算一次. 先计…
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]$代表这个点所能表示的最长串长度),这也就是后缀自动机上每个点贡献的子串个数.对于每个点…