摘要: 首先只有lcp(i,j)需要考虑 因为SAM的parent树是后缀的前缀的最长公共后缀(……),所以把这个串倒过来建SAM,这样就变成了求两个前缀的最长公共后缀,长度就是这两个前缀在parent树上的lcs对应的最大长度dis 这里用treedp解决即可,就是合并一下size cpp include 阅读全文
posted @ 2018-11-23 22:01 lokiii 阅读(131) 评论(0) 推荐(0) 编辑
摘要: AC自动机比较简单,把询问串做成AC自动机然后模板串边跑变更新即可 SAM是把模板串做成广义SAM,然后每个节点存有几个模板串经过,具体方法是每次更新暴力向上跳直到有时间戳~~我不会证为什么时间复杂度是对的~~,沿途更新个数,查询的时候直接匹配到最后的点然后输出个数即可 cpp include in 阅读全文
posted @ 2018-11-23 19:51 lokiii 阅读(145) 评论(0) 推荐(0) 编辑
摘要: 把模板串建一个广义SAM 然后在线查询,每次在SAM上预处理出一个a[i]表示i位置向前最多能匹配多长的模板串 二分答案L,dp判断,设f[i]为·~i有几个匹配,转移显然是f[i]=max{f[i 1],f[j]+i j(i a[i]=L\ 0.9 阅读全文
posted @ 2018-11-23 18:39 lokiii 阅读(138) 评论(0) 推荐(0) 编辑
摘要: 差分之后用SAM求LCS,然后答案就是LCS+1 cpp include include include using namespace std; const int N=2005; int n,m,s[N],b[N],fa[N],ch[N][205],dis[N],cur=1,con=1,la,f 阅读全文
posted @ 2018-11-23 17:01 lokiii 阅读(157) 评论(0) 推荐(0) 编辑
摘要: 有一个显然的性质就是每个串一定在某个叶子为根的树中是一条直的链 然后因为SAM里是不会有相同状态的,所以以每个叶子为根dfs一遍,并且动态构造SAM(这里的节点u的last指向父亲),最后统计答案就是dis[i] dis[fa[i]]的和 我看别的题解都说和trie有关……然而并没用用到(也可能是用 阅读全文
posted @ 2018-11-23 16:34 lokiii 阅读(130) 评论(0) 推荐(0) 编辑
摘要: SAM里的转台不会有重复串,所以答案就是每个right集合所代表的串个数的和 cpp include include include using namespace std; const int N=100005; int T,n,fa[N],ch[N][27],dis[N],cur=1,con=1 阅读全文
posted @ 2018-11-23 15:59 lokiii 阅读(159) 评论(0) 推荐(0) 编辑
摘要: 多串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,l 阅读全文
posted @ 2018-11-23 09:39 lokiii 阅读(148) 评论(0) 推荐(0) 编辑
摘要: 先求出SAM,然后考虑定义,点u是一个right集合,代表了长为dis[son]+1~dis[u]的串,然后根据有向边转移是添加一个字符,所以可以根据这个预处理出si[u],表示串u后加字符能有几个本质不同子串 然后回答的时候在树上跑一下即可 阅读全文
posted @ 2018-11-23 07:57 lokiii 阅读(155) 评论(0) 推荐(0) 编辑