题目

一个长度为n的字符串S,令TiT_i表示它从第i个字符开始的后缀.求

∑1≤i<j≤nlen(Ti)+len(Tj)−2∗lcp(Ti,Tj)

\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 差异 [后缀自动机]相关推荐

  1. bzoj3238 [Ahoi2013]差异 后缀自动机

    这个题虽然看起来比较麻烦,但其实有一点搞懂了就好做了 每一个后缀的前缀的lcp一定是这个串里的子串, 对于全部子串,如果它不是后缀,那一定可以找到这个串对应的后缀, 而这样的子串和后缀子串是没有区别的 ...

  2. bzoj 3238 差异

    给出一个长n的字符集为小写字母的字符串,求∑1≤i<j≤nlen(Suffixi)+len(Suffixj)−2×len(lcp(Suffixi,Suffixj))\sum \limits _{ ...

  3. bzoj3238 [Ahoi2013]差异 后缀自动机

    题意:给出一个串,求其中任意两个字串的lcp的总和. 我们可以对于这个串建一颗后缀自动机,实际上,他的parent边树就是一颗后缀树,我们在后缀树上统计答案,设f表示right集合的大小,可以理解为后 ...

  4. 后缀自动机+DP BZOJ 3238 差异

    分析: 其实题目就是要求任意两个后缀T[i]和T[j] (i< j) 的 LCP长度之和. 首先对输入的字符串反转后建立SAM. 令 一个节点的Max表示它代表的最长子串. 推论1: 原串中的两 ...

  5. 【bzoj3238】差异 后缀自动机

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=3238 [题解] 题上所给公式可以化为 其中: =1×(n-1)+2×(n-2)+3×(n- ...

  6. [BZOJ3238] [AHOI2013] 差异 - 后缀自动机

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 1968  Solved: 896 [Submit][Statu ...

  7. BZOJ.2555.SubString(后缀自动机 LCT)

    题目链接 \(Description\) 给你一个字符串init,要求支持两个操作: (1)在当前字符串的后面插入一个字符串s (2)询问字符串s在当前字符串中出现了几次(作为连续子串) 强制在线. ...

  8. BZOJ 2555: SubString [后缀自动机 LCT]

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MB Submit: 2045  Solved: 583 [Submit][Status][ ...

  9. [BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】

    题目链接:BZOJ - 3238 题目分析 显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显. 求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组. 那么 ...

最新文章

  1. 关于android基础教程一书的初步解读后发现的一些问题
  2. GiliSoft Video Editor 13中文版
  3. 测试wifi网络常用软件,网络基础-常用网络测试工具
  4. Babylon-AST初探-代码更新删除(Update Remove)
  5. 1.9 编程基础之顺序查找 09 直方图 9分 python
  6. C#进行MapX二次开发之图层操作
  7. 自编自适应中值滤波器
  8. GBase 8s 管理员常用命令
  9. 通达OA前台任意用户登录漏洞复现
  10. 寻找春天nbsp;九宫格日记-2011.08.24
  11. [麻将] 麻将的一些概率计算
  12. mysql当前时间相减_mysql 查询当前时间加减时间
  13. QuartusII 15.0 中解决仿真报错 Error : vism-19 Faild to access library问题
  14. Percentile和Quartile
  15. 解决C#读取文本文件乱码
  16. PTA 7-152 百钱百鸡
  17. [Python图像处理] 二十九.MoviePy视频编辑库实现抖音短视频剪切合并操作
  18. 利用arcgis-ArcMap手动快速检查重庆三调图斑的方法探讨与自动化检查的想法
  19. 使用 VS Studio 2022 创建自己的 NuGet包,图片教程包教包会!
  20. Python办公自动化实战 13 | Python-docx库:Python与Word的完美结合_学员考试准考证批量生成

热门文章

  1. Talk | 清华大学交叉信息研究院助理教授杜韬:利用计算方法探究流固耦合
  2. 动态链接库和静态链接库
  3. 数据资产价值评估与定价:研究综述和展望
  4. idea 将分支代码合并到master分支
  5. 【Python语言】Python编程基础
  6. Linux内核的删除
  7. 蓝屏总结(一) ——基本分析方法
  8. oracle 求时间均值
  9. RARP:反向地址转换协议
  10. IC卡·一卡一密加密 动态数据防伪方案实现