2555: SubString[LCT+SAM]】的更多相关文章

2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MB Submit: 2601  Solved: 780 [Submit][Status][Discuss] Description 懒得写背景了,给你一个字符串init,要求你支持两个操作          (1):在当前字符串的后面插入一个字符串          (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)          你必须在线支持这些操作.      In…
2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 2548  Solved: 762 Description 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支持这些操作. Input 第一行一个数Q表示操作个数        第二行一个字符串表示初始字符串init        接下来Q行,每…
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2555 [题意] 给定一个字符串,可以随时插入字符串,提供查询s在其中作为连续子串的出现次数. [思路] 子串的出现次数,这使我们想到了后缀自动机,如果没有插入操作,则出现次数为字符串对应节点|right|集的大小. Right的递推方法为:|fa->right| <- |right| 如果暴力做的话,可以每一次插入都重新计算right.时间复杂度为O(mn). 因为需要不断地插入字…
$ \color{#0066ff}{ 题目描述 }$ 给定一个字符串init,要求支持两个操作 在当前字符串的后面插入一个字符串 询问字符串ss在当前字符串中出现了几次?(作为连续子串) 强制在线. \(\color{#0066ff}{输入格式}\) 第一行一个整数\(Q\)表示操作个数 第二行一个字符串表示初始字符串init 接下来Q行,每行2个字符串Type,Str Type是ADD,表示在后面插入字符串. Type是QUERY,表示询问某字符串在当前字符串中出现了几次. 为了体现在线操作,…
2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 688  Solved: 235[Submit][Status][Discuss] Description 懒得写背景了,给你一个字符串init,要求你支持两个操作          (1):在当前字符串的后面插入一个字符串          (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)          你必须在线支持这些操作. Input 第一行一…
2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1620  Solved: 471 Description 懒得写背景了,给你一个字符串init,要求你支持两个操作          (1):在当前字符串的后面插入一个字符串          (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)          你必须在线支持这些操作. Input 第一行一个数Q表示操作个数          第二行一个…
喜闻乐见的LCT+SAM 此题要求动态插入,直接上后缀树.然后询问其实就是求一个节点的子树后缀结束节点的个数. 因为建立后缀树需要插入和删除,就直接上LCT.每次加入一个点,把它到根的路径加一 (现在我才知道access之后那个splay就是这个点到根的路径,LCT学得不好) 思路不需要说太多,就是码量大. #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #i…
2555: SubString 链接 题意: 动态在末尾加入一个字符串,询问一个字符串出现了多少次. 分析: 如果没有动态加入,那么建出SAM后,求出parent树上,每个点|Right|,然后走一遍找到对应的点,这个点的Right集合的大小就是答案. 求Right可以从叶子结点往上走一遍. 考虑动态加入,那么会在parent树上,增加一点,并且支持加边删边,求一个点的权值,在一条到根的链上增加一个数,所以LCT维护parent树. 代码: #include<cstdio> #include&…
2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 3253  Solved: 975[Submit][Status][Discuss] Description 懒得写背景了,给你一个字符串init,要求你支持两个操作        (1):在当前字符串的后面插入一个字符串        (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)        你必须在线支持这些操作. Input 第一行一个数Q表示…
Description 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支持这些操作. Input 第一行一个数Q表示操作个数 第二行一个字符串表示初始字符串init 接下来Q行,每行2个字符串Type,Str Type是ADD的话表示在后面插入字符串. Type是QUERY的话表示询问某字符串在当前字符串中出现了几次. 为了体现在线操作,你需要维护一个变量mask,初始…
传送门 题意简述: 要求在线支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 思路: 考虑用lctlctlct来动态维护samsamsam的rightrightright集合. 代码: #include<bits/stdc++.h> #define ri register int using namespace std; const int N=1200005; char s[N]; int n; string str; i…
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2555 要维护 right 集合的大小.因为 fa 会变,且 fa 构成一棵树,所以考虑用 LCT 来维护…… 和平常写的 LCT 不太一样.因为要的值是原树上子树里的值,所以没有 makeroot ,splay 里不维护 splay 里的子树信息,只维护加法标记,表示 link 一下就给原树的自己到根的那条链上的所有点加了自己的值.cut 就是减掉自己的值.所以 query 或者 spla…
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2555 建立后缀自动机,就可以直接加入新串了: 出现次数就是 Right 集合的大小,需要查询 Parent 树上的子树和: 所以可以用 LCT 维护 Parent 树,因为 Parent 树是有根树所以不需要 makeroot: 代码中的两种 cut 写法都可以,其实这里的 splay 节点上记的 siz 值不是 splay 子树里的而是原子树( Parent 树上)里的: 注意读入的函数…
一直WA--找了半天错的发现居然是解密那里的mask其实是不能动的--传进去的会变,但是真实的那个不会变-- 然后就是后缀自动机,用LCT维护parent树了--注意不能makeroot,因为自动机的根是不会变的(同理也不能翻转区间),其实就是低配LCT(?) #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=3000005; int q,n,m,…
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2555题解: 后缀自动机+LCT 不难发现,对于输入的询问串,在自动机里trans后的到的状态的Right集合的大小就是答案. 那么后缀自动机本身就是支持在线添加的,问题就是如何维护好parent树,即如何维护好每个状态的Right集合. 那么Link-Cut-Tree就显然可以完成动态维护parent树的任务. (这里是维护的一颗根固定的树,没有Beroot()等换根函数) 代码: #in…
BZOJ2555. SubString 要求在线询问一个串在原串中出现的次数,并且可以在原串末尾添加字符串 如果没有修改的话,考虑建出\(parent\)树之后统计每个\(endpos\)节点的\(right\)集合大小,现在要求动态添加字符,那么由于\(parent\)树的形态会变,所以用\(LCT\)来维护\(parent\)树,具体就是增删\(link\)边 \(LCT\)一直以初始状态为根,每次提出来初始状态到当前节点的链然后更新一条链上的值即可,根一直没变,不需要\(makeroot\…
A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\sum\) is the set of lowercase letters. Substring, also called factor, is a consecutive sequence of characters occurrences at least once in a string. N…
http://www.lydsy.com/JudgeOnline/problem.php?id=2555 学到了如何快速维护right值orz (不过这仍然是暴力维护,可以卡到O(n) 首先我们在加一个新节点的时候直接遍历它的parent树就行啦啦!!!!这样直接就暴力维护了...我竟然没想到.. 然后在复制新节点的时候不要忘记将right也要赋值进去.. 然后就是裸题了 #include <cstdio> #include <cstring> #include <cmath…
Code: #include<bits/stdc++.h> #define maxn 200003 using namespace std; void setIO(string s) { string in=s+".in", out=s+".out"; freopen(in.c_str(),"r",stdin); // freopen(out.c_str(),"w",stdout); } int n,Q; int…
很水的一道题,就是有些细节没注意到. 比如说将调试信息误以为是最终结果而多调了20分钟QAQ ..... 我们注意到,每新加一个节点,改变的是该节点沿着 Parent 走一直走到根节点. 对应的,在 LCT 上进行修改即可. 改变一个节点的 Parent,就对应 cut 断掉原边后将新边连接即可. Code: #include <cstdio> #include <algorithm> #include <cstring> #define setIO(s) freope…
LINK:字符串 看起来很难做 考虑一种暴力 建立SAM后每次查询暴力扫儿子. 期望得分10分.实际得分10分. 另外一种发现每次扫儿子过于暴力 可以每次儿子向上做贡献 每次都暴力向上跳. 期望得分10分.实际得分100分. 由此可以发现玄学的暴力非常的强大 可能这就是所谓的暴力出奇迹吧. 考虑离线:这样就可以把SAM给建出来了 进一步的 每次询问是查询子树和. 每次修改是单点修改 可以利用线段树维护dfs序就做完了. 不过其中存在细节 分裂的节点是影响答案的统计的. 怎么处理分裂的节点?注意到…
正题 题目链接:https://www.luogu.com.cn/problem/P5212 题目大意 开始一个字符串\(S\),有\(n\)次操作 在\(S\)末尾加入一个字符串 询问一个串在\(S\)中出现了多少次 强制在线 解题思路 强制在线的话,只有\(\text{SAM}\)能够支持动态插字符了,但是我们平时统计答案的时候要先做一次拓扑排序然后上传信息. 这里要动态维护\(\text{parents}\)树的话用\(\text{LCT}\)就好了,就是链修改加单点查询,然后因为根是指定…
Description 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支持这些操作. Solution 思路比较直观啊 首先没有插入的话,预处理好每个点 \(|right|\) 就好了 如果有插入的话我们发现实际上就是维护一个子树大小 每一次插入一个节点就相当于把父亲到根路径上的权值全部 \(+1\) 我们用 \(LCT\) 维护这个加边删边和路径加法的操作 每一次询问…
原文链接http://www.cnblogs.com/zhouzhendong/p/8982392.html 题目传送门 - SPOJ LCS 题意 求两个字符串的最长公共连续子串长度. 字符串长$\leq 250000$ 题解 首先对于第一个字符串建一个$SAM$. 然后拿第二个串在$SAM$上面走一遍就好了. 具体地: 将第二个串的字符一个一个地按照顺序加入. 设当前状态为$now$,要加入字符$c$,当前匹配的字符串长度为$len$(答案自然是各种情况下$len$的最大值). 如果在$SA…
/* 动态求right集合的大小 LCT维护parent树即可 注意 由于树是有向的不会换根并且每次操作单一, 于是不需要维护子树和(写起来很麻烦) 直接打标记修改即可 */ #include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<queue> #define ll long long #define M 1200010 #define…
多串LCS很适合SA但是我要学SAM 对第一个串求SAM,然后把剩下的串在SAM上跑,也就是维护p和len,到一个点,如果有ch[p][c],就p=ch[p][c],len++,否则向fa找最下的有c[p][c]的p,然后len=dis[p]+1,p=ch[p][c],否则就p=root,len=0(这个len每到一个节点就更新这个节点的f) 然后注意到在parent树上,因为每个节点代表的right集合是儿子的并集,所以f[u]是可以更新f[fa[u]]的,所以从底向上更新一遍(注意先更新!!…
传送门 洛谷 Solution 考虑他要求的是最长公共子串对吧,那么我们对于一个串建后缀自动机,另一个串在后缀自动机上面跑就是了. 复杂度\(O(n+m)\)的,很棒! 代码实现 代码戳这里…
1600 Simple KMP 对于一个字符串|S|,我们定义fail[i],表示最大的x使得S[1..x]=S[i-x+1..i],满足(x<i)显然对于一个字符串,如果我们将每个0<=i<=|S|看成一个结点,除了i=0以外i向fail[i]连边,这是一颗树的形状,根是0我们定义这棵树是G(S),设f(S)是G(S)中除了0号点以外所有点的深度之和,其中0号点的深度为-1定义key(S)等于S的所有非空子串S'的f(S')之和给定一个字符串S,现在你要实现以下几种操作:1.在S最后面…
2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1936  Solved: 551[Submit][Status][Discuss] Description 懒得写背景了,给你一个字符串init,要求你支持两个操作    (1):在当前字符串的后面插入一个字符串    (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)    你必须在线支持这些操作. Input 第一行一个数Q表示操作个数    第二行一…
SAM练习记录 洛谷 P1368 工艺 其实是最小表示法裸题 倍长后建SAM跑最小的边走|S|步即可 Code CF 235 C. Cyclical Quest 对主串建SAM 然后每个串倍长,跑的时候维护一下匹配长度再更新答案,还有判断一个节点是否重复到达. Code BZOJ1396: 识别子串 一开始写这个题的时候固执的认为是线段树合并.. 显然出现次数为1的串的rigit集合大小为1,我们直接处理一下就好了,设Ta和Ta父亲的长度是\(len_x\)和\(len_p\) 那么在区间\([…