BZOJ1396 识别子串【SAM+SegmentTree】】的更多相关文章

Description Input 一行,一个由小写字母组成的字符串S,长度不超过10^5 Output L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长. Sample Input agoodcookcooksgoodfood Sample Output 1 2 3 3 2 2 3 3 2 2 3 3 2 1 2 3 3 2 1 2 3 4 Solution 1A挺开心的省得调了对于SAM上的每一个节点,我们只需要考虑right集合大小为1的设一个right集合大小为…
BZOJ1396 识别子串 给定一个串\(s\),对于串中的每个位置,输出经过这个位置且只在\(s\)中出现一次的子串的最短长度 朴素的想法是,我们要找到那些只出现一次的子串,之后遍历每个串,把串所覆盖的区域区间和串长取\(min\) 考虑优化,根据\(s\)串先建立\(SAM\),然后计算出每个状态的\(endpos\)集合的大小,其中大小为\(1\)的状态所表示的一系列子串必然只在原串中出现一次,对于\(endpos\)大小为\(1\)的某个状态\(u\),其表示的子串的最短长度为\(len…
后缀自动机+线段树 先建出\(sam\),统计一遍每个点的\(right\)集合大小\(siz\),对于\(siz=1\)的点\(x\),他所代表的子串只会出现一次,设\(y=fa[x]\),则这个点代表的子串即为\((1...len[x]-len[y],len[x])\),对于子串\((len[x]-len[y],len[x])\)的每一个点,这个子串都是他的识别子串,长度固定\(len[y]+1\),而对于一个点\(i\in[1,len[x]-len[y]-1]\),子串\((i,len[x…
字符串识别 2865: 字符串识别 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 839  Solved: 261[Submit][Status][Discuss] Description XX在进行字符串研究的时候,遇到了一个十分棘手的问题. 在这个问题中,给定一个字符串S,与一个整数K,定义S的子串T=S(i, j)是关于第K位的识别子串,满足以下两个条件: 1.i≤K≤j. 2.子串T只在S中出现过一次. 例如,S="banana"…
https://www.lydsy.com/JudgeOnline/problem.php?id=1396 后缀自动机的parent树上,如果不是叶子节点,那么至少有两个子节点 而一个状态所代表子串的出现次数就是子树中叶子节点的个数 所以只有叶子节点 即 |Right|=1的状态 代表的子串 出现了1次 我们计算以每一个位置为子串右端点时,它对一些位置的贡献 枚举|Right|=1的状态s 令end=Right(s) 那么以end为子串右端点,长度在[1,Max(parent(s))]的子串至少…
Description Input 一行,一个由小写字母组成的字符串S,长度不超过10^5 Output L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长. Sample Input agoodcookcooksgoodfood Sample Output 1 2 3 3 2 2 3 3 2 2 3 3 2 1 2 3 3 2 1 2 3 4 解题思路: 思考一个最小识别串会带来什么. 在它内部的点的答案就是这个串的长度,而在它外面的点需要拓展到这个串的端点. 首先,一…
原文链接http://www.cnblogs.com/zhouzhendong/p/9004467.html 题目传送门 - BZOJ1396 题意 给定一个字符串$s$,$|s|\leq 10^5$. 对于$s$的每一个位置,求$s$的包含该位置的.仅在$s$中出现一次的连续子串的最短长度. 题解 考虑先对于$s$构建一个后缀自动机. 由于我们要考虑的串是只能在$s$中出现一次的. 所以我们先基数排序,然后通过$fa$指针计算每一个节点的$Right$集合. 只出现一次的就是$Right$集合…
复习SAM板子啦!考前刷水有益身心健康当然这不是板子题/水题…… 很容易发现只在i位置出现的串一定是个前缀串.那么对答案的贡献分成两部分:一部分是len[x]-fa~len[x]的这部分贡献会是r-l+1:剩下一部分1~len-fa-1这部分会和i~r构成答案,写两棵线段树即可. 然后就又是板子题了,两个板子(SAM+线段树)套起来. #include<bits/stdc++.h> #define lson l,mid,rt<<1 #define rson mid+1,r,rt&l…
题面: bzoj1396 题解: 先建出SAM,并计算right集合大小.显然符合条件的点的right集合大小为1. 对于每个right集合为1的状态显然可以算出这些状态的pos以及maxlen和minlen(fa的len+1). 然后对于在pos和pos-minlen+1区间内的字符显然必须选长为minlen的一段区间.因此我们搞一棵线段树维护这些minlen,即对于在pos和pos-minlen+1区间内的字符在线段树上和minlen取min 对于另外的在pos-maxlen+1到pos-m…
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define maxn 100005 #define inf 100000000 using namespace std; char st[maxn]; ],tmp[maxn<<],fa[maxn<<],son[maxn<<…