解题:NOI2018 你的名字(68pts暴力)】的更多相关文章

题面 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…
讲解在满分做法的博客中 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真让人头秃. 题面 https://www.luogu.org/problemnew/show/P4770 首先考虑 l=1,r=∣S∣的做法 如果对于ION2018的子串不用判重的话,对ION2017建SAM跑一遍就好了. 此时ION2018的每一个前缀对答案的贡献为前缀长度-匹配长度. 考虑怎么去重. 这应该算是SAM比较常用去重的一种套路. 对ION2018建出SAM. 原本就算答案的方式是枚举子串的右端点的位置. 现在改为枚举枚举SAM上的节点. 由于对于每种串要只计算一次. 先计…
[BZOJ5417][NOI2018]你的名字(线段树,后缀自动机) 题面 BZOJ 洛谷 题解 首先考虑\(l=1,r=|S|\)的做法,对于每次询问的\(T\)串,暴力在\(S\)串的\(SAM\)上跑,对于每个点记录其被匹配的最大长度,然后把每个被匹配到的点以及它到\(parent\)树根节点的所有节点全部计算一下能够被匹配的最大长度,最后计算一下有多少个串在\(S\)中出现过.拿总方案减去不合法就行了. 然后现在\(l,r\)任意,那么首先线段树合并求出所有的\(endpos\). 一样…
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]$代表这个点所能表示的最长串长度),这也就是后缀自动机上每个点贡献的子串个数.对于每个点…
传送门 UPD:发现之前被smy误导的一个细节,改过来之后就AC了-- 一道比较套路的SAM题,虽然我连套路都不会-- 先考虑前\(68pts\),也就是\(l=1 , r=|S|\)的情况.我们对\(S\)建好SAM,把\(T\)扔到\(S\)的SAM上匹配,如果不考虑本质不同子串的性质,那么答案就是\(\sum\limits_{i=1}^{|T|} i - l_i\),其中\(l_i\)是匹配到第\(i\)个字符时的匹配长度. 然后考虑如何去重.对\(T\)也建SAM,把\(T\)也放在\(…
看到题目名字去补番是种怎么样的体验 我只会 \(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…
题目 可能是一个乱搞做法,同时也跪求有人能帮我分析一下复杂度 还是先来看比较简单的\(68pts\),也就是\(l=1,r=|S|\)的情况 我们可以直接把\(S\)串和所有的\(T\)串一起建一个广义\(SAM\),用一个\(vector\)维护每个\(T\)加入\(SAM\)时新产生的节点 我们只需要求出来这些新增节点没有在\(S\)串出现的本质不同的子串个数就好了 我们提前处理好每一个节点的\(endpos\),标记一下其是否在\(S\)中出现过 对于那些新出现在\(SAM\)上的节点\(…
题解: 前68分非常简单 建立SAM 另一个串在上面跑,然后求一个树链的并 我们会发现暴力就是min(l^2,n)的 所以复杂度最多是nsqrt(n)的 当然我们也可以nlogn维护 把所有点按照dfs序排序,每个点到根的距离减去排序后 相邻两点LCA到根的距离就是树链的并的长度 不过要注意一下由于有权值 所以每个点在当前点可能只取了一部分权值 调试的时候发现 cnt没清空 *** windows下不开O2不会跑到其他数组里,开了O2就会跑到其他数组里 linux下开不开都会跑过去 linux下…