BZOJ 3238 差异 [后缀自动机]
题目
一个长度为n的字符串S,令TiT_i表示它从第i个字符开始的后缀.求
\sum_{1\le i
其中len(a)表示字符串a的长度,lcp(a,b)表示字符串a和字符串b的最长公共前缀.
输入
一行,一个字符串S
输出
一行,一个整数,表示所求值
样例输入
cacao
样例输出
54
注意
2≤N≤5000002\le N\le500000,S由小写英文字母组成
分析
这道题需要我们记住一个结论 ! ! !
!反串建后缀自动机的parent树是原串的后缀树!
对于这道题,我们不难发现,原串后缀树上两节点的最近公共祖先的层数就是两子串的lcp,我们可以从叶子结点开始往父亲节点走,根据题目要求就是求出所有公共前缀,我们可以边记录边更新,具体操作可以参考代码第63,64行!
完整代码
#include<bits/stdc++.h>
#define maxn 500010
#define maxt 1000010
//#define DEBUG
using namespace std;
int n;
long long ans=0;
int sum[maxt],tmp[maxt];
long long total[maxt];
char ch[maxn];struct SAM
{int root,last,tot;int r[maxt],fa[maxt],son[maxt][26],maxl[maxt];int addnode(int x) { return maxl[++tot]=x,tot; }void init() { root=last=tot=1; }void add(int pos){int x=ch[pos]-'a',p=last,np=addnode(maxl[p]+1);last=np,r[np]=total[np]=1;for( ; p&&!son[p][x] ; p=fa[p] ) son[p][x]=np;if(!p) fa[np]=root;else{int q=son[p][x];if(maxl[q]==maxl[p]+1) fa[np]=q;else{int nq=addnode(maxl[p]+1);memcpy(son[nq],son[q],sizeof(son[q]));fa[nq]=fa[q];fa[q]=fa[np]=nq;for( ; son[p][x]==q ; p=fa[p] ) son[p][x]=nq;}}}void Tsort(){for(int i=1;i<=tot;++i) sum[maxl[i]]++;for(int i=1;i<=n;++i) sum[i]+=sum[i-1];for(int i=1;i<=tot;++i) tmp[sum[maxl[i]]--]=i;}void treeDP(){for(int i=tot;i;--i) r[fa[tmp[i]]]+=r[tmp[i]];for(int i=tot;i;--i){int x=tmp[i];ans+=1ll*total[fa[x]]*r[x]*maxl[fa[x]]; //不加1ll可能会溢出!total[fa[x]]+=r[x]; //63,64为核心步骤!}}void build(){init();scanf("%s",ch+1);n=strlen(ch+1);for(int i=n;i;--i) add(i);Tsort();treeDP();}} sam ;int main()
{
#ifdef DEBUGfreopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endifsam.build();printf("%lld\n",1ll*(n-1)*(n+1)*n/2-ans*2);return 0;
}
BZOJ 3238 差异 [后缀自动机]相关推荐
- bzoj3238 [Ahoi2013]差异 后缀自动机
这个题虽然看起来比较麻烦,但其实有一点搞懂了就好做了 每一个后缀的前缀的lcp一定是这个串里的子串, 对于全部子串,如果它不是后缀,那一定可以找到这个串对应的后缀, 而这样的子串和后缀子串是没有区别的 ...
- bzoj 3238 差异
给出一个长n的字符集为小写字母的字符串,求∑1≤i<j≤nlen(Suffixi)+len(Suffixj)−2×len(lcp(Suffixi,Suffixj))\sum \limits _{ ...
- bzoj3238 [Ahoi2013]差异 后缀自动机
题意:给出一个串,求其中任意两个字串的lcp的总和. 我们可以对于这个串建一颗后缀自动机,实际上,他的parent边树就是一颗后缀树,我们在后缀树上统计答案,设f表示right集合的大小,可以理解为后 ...
- 后缀自动机+DP BZOJ 3238 差异
分析: 其实题目就是要求任意两个后缀T[i]和T[j] (i< j) 的 LCP长度之和. 首先对输入的字符串反转后建立SAM. 令 一个节点的Max表示它代表的最长子串. 推论1: 原串中的两 ...
- 【bzoj3238】差异 后缀自动机
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=3238 [题解] 题上所给公式可以化为 其中: =1×(n-1)+2×(n-2)+3×(n- ...
- [BZOJ3238] [AHOI2013] 差异 - 后缀自动机
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 1968 Solved: 896 [Submit][Statu ...
- BZOJ.2555.SubString(后缀自动机 LCT)
题目链接 \(Description\) 给你一个字符串init,要求支持两个操作: (1)在当前字符串的后面插入一个字符串s (2)询问字符串s在当前字符串中出现了几次(作为连续子串) 强制在线. ...
- BZOJ 2555: SubString [后缀自动机 LCT]
2555: SubString Time Limit: 30 Sec Memory Limit: 512 MB Submit: 2045 Solved: 583 [Submit][Status][ ...
- [BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】
题目链接:BZOJ - 3238 题目分析 显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显. 求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组. 那么 ...
最新文章
- 关于android基础教程一书的初步解读后发现的一些问题
- GiliSoft Video Editor 13中文版
- 测试wifi网络常用软件,网络基础-常用网络测试工具
- Babylon-AST初探-代码更新删除(Update Remove)
- 1.9 编程基础之顺序查找 09 直方图 9分 python
- C#进行MapX二次开发之图层操作
- 自编自适应中值滤波器
- GBase 8s 管理员常用命令
- 通达OA前台任意用户登录漏洞复现
- 寻找春天nbsp;九宫格日记-2011.08.24
- [麻将] 麻将的一些概率计算
- mysql当前时间相减_mysql 查询当前时间加减时间
- QuartusII 15.0 中解决仿真报错 Error : vism-19 Faild to access library问题
- Percentile和Quartile
- 解决C#读取文本文件乱码
- PTA 7-152 百钱百鸡
- [Python图像处理] 二十九.MoviePy视频编辑库实现抖音短视频剪切合并操作
- 利用arcgis-ArcMap手动快速检查重庆三调图斑的方法探讨与自动化检查的想法
- 使用 VS Studio 2022 创建自己的 NuGet包,图片教程包教包会!
- Python办公自动化实战 13 | Python-docx库:Python与Word的完美结合_学员考试准考证批量生成