BZOJ3238:[AHOI2013]差异(SAM)】的更多相关文章

Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Output 54 HINT 2<=N<=500000,S由小写英文字母组成 Solution 后缀自动机的fa指针反向以后可以形成一个树结构,称作Parent树一个节点的father是他的最长后缀,那么很显然任意两个子串的最长公共后缀位于它们Parent树对应节点的lca处为了利用这个性质,可以把串反过来建立SAM,问题转化成对这个串的所有前缀…
BZOJ3238 [Ahoi2013]差异 给定一个串,问其任意两个后缀的最长公共前缀长度的和 1.又是后缀,又是\(lcp\),很显然直接拿\(SA\)的\(height\)数组搞就好了,配合一下单调栈 //#pragma GCC optimize("O3") //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<bits/stdc++.h> using namespace…
[bzoj3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Output 54 题解: 任意两个字符串的lcp是什么,就是如 a,b  那么若a==b 那么为len(a) 否则设sa[a]<sa[b] 那么为min(height[sa[a]+1-------sa[b]]) #include<cstring> #include<iostream>…
差异 bzoj-3238 Ahoi-2013 题目大意:求任意两个后缀之间的$LCP$的和. 注释:$1\le length \le 5\cdot 10^5$. 想法: 两个后缀之间的$LCP$和显然不好求. 我们先构建后缀数组. 那么任意两个后缀之间的$LCP$之和就是所有$sa$数组上所有区间的$ht$最小值. 换言之,我们有一个$a$数组. 显然让你求所有区间的权值和. 一个区间的权值为这个区间内所有$a_i$的最小值. 这个过程我们可以用单调栈实现. Code: #include <io…
luogu P4248 [AHOI2013]差异 链接 luogu 思路 \(\sum\limits_{1<=i<j<=n}{{len}(T_i)+{len}(T_j)-2*{lcp}(T_i,T_j)}\) =\(\sum\limits_{1<=i<j<=n}{{len}(T_i)+{len}(T_j)}-\sum\limits_{1<=i<j<=n}2*{lcp}(T_i,T_j)\) 前半部分是\(\frac{n*(n+1)(n-1)}{2}\)…
Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Output 54 HINT 2<=N<=500000,S由小写英文字母组成 YY了后缀自动机的解法: 首先题意就是让你求sigma(LCP(i,j)|i<j) 将字符串反过来,考虑两个后缀对答案的贡献,其实就是节点x和y的lca节点包含的最长子串长度 那么将SAM构出来,考虑当LCA为节点z时,有多少满足条件的(x,y),这个枚举z的相邻…
传送门 后缀自动机好题. 题意: 做法:samsamsam 废话 考虑翻转字串,这样后缀的最长公共前缀等于前缀的最长公共后缀. 然后想到parentparentparent树上面两个串的最长公共后缀跟他们所处状态的lcalcalca有关系. 于是对于每一个lcalcalca都处理出它的sizesizesize和maxlengthmax_{length}maxlength​就行了. 代码: #include<bits/stdc++.h> #define ri register int using…
求和式的前两项可以直接算,问题是对于每对i,j计算LCP. 一个比较显然的性质是,LCP(i,j)是h[rk[i]+1~rk[j]]中的最小值. 从h的每个元素角度考虑,就是对每个h计算有多少对i,j以它为最小值. 在h中使用单调栈统计左右比它小的第一个元素,相乘得到结果. #include<cstdio> #include<cstring> #include<algorithm> #define rep(i,l,r) for (int i=(l); i<=(r)…
Description 先分析一下题目,我们显然可以直接算出sigma(len[Ti]+len[Tj])的值=(n-1)*n*(n+1)/2 接着就要去算这个字符串中所有后缀的两两最长公共前缀总和 首先可以想到后缀数组,我们计算好后缀数组之后再进行对height数组的计算 对于以x,y开头的后缀,它们的最长公共前缀为min(height[sa[i]])(rank[x]<=i<=rank[y]) 但从以往习惯的height数组入手我们发现并没有办法解决这个问题 不如换个角度思考,我们可以枚举这个…
Brief Description Algorithm Design 下面给出后缀自动机的一个性质: 两个子串的最长公共后缀,位于这两个串对应的状态在parent树上的lca状态上.并且最长公共后缀的长度就是lca状态的len. 证明:对于一个串,他的所有祖先节点都是他的后缀,并且深度越大,长度越长,由此不难说明两个子串的最长公共后缀一定在lca状态上.考察这个lca,他代表的所有子串一定都是两个子串的公共后缀,我们直接取最大的就可以了. 有了这个性质,我们就可以开始乱搞了. Code #inc…