BZOJ.3238.[AHOI2013]差异(后缀自动机 树形DP/后缀数组 单调栈)

时间:2022-01-31 00:18:01

题目链接

\(Description\)

BZOJ.3238.[AHOI2013]差异(后缀自动机 树形DP/后缀数组 单调栈)

\(Solution\)

len(Ti)+len(Tj)可以直接算出来,每个小于n的长度会被计算n-1次。

\[\sum_{i=1}^n\sum_{j=i+1}^n i+j = (n-1)*\sum_{i=1}^n = (n-1)*\frac{n*(n+1)}{2}
\]

对于后半部分:

SAM:求后缀的LCP,我们可以想到将字符串反转,求前缀的最长公共后缀。

parent树上每个叶子节点都对应一个前缀,两个节点间的最长公共后缀在它们的LCA处,长度为len[LCA]。

于是对于每个节点我们统计有多少对叶子节点的LCA为它。树形DP就可以了。

非后缀节点的size是等于0,但是最后一样DP。

SA:LCP当然是看height了。枚举后缀,计算它与之前串所构成的LCP。

如果ht[i]>=ht[i-1],那么它与之前串的LCP和i-1一样;否则ht[i]就是这部分的LCP长度。

用单调栈维护离i最近且ht[p]<=i的位置p,则f[i]=f[p]+(i-p)*ht[i]。

//122404kb	1924ms
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=1e6+5; struct Suffix_Automaton
{
int n,las,tot,fa[N],son[N][26],len[N],sz[N],A[N],tm[N];
char s[N>>1];
void Insert(int c)
{
int p=las,np=++tot;
len[las=np]=len[p]+1, sz[np]=1;
for(; p&&!son[p][c]; p=fa[p]) son[p][c]=np;
if(!p) fa[np]=1;
else
{
int q=son[p][c];
if(len[q]==len[p]+1) fa[np]=q;
else
{
int nq=++tot; len[nq]=len[p]+1;
memcpy(son[nq],son[q],sizeof son[q]);
fa[nq]=fa[q], fa[q]=fa[np]=nq;
for(; son[p][c]==q; p=fa[p]) son[p][c]=nq;
}
}
}
void Build()
{
las=tot=1;
scanf("%s",s+1), n=strlen(s+1);
std::reverse(s+1,s+1+n);
for(int i=1; i<=n; ++i) Insert(s[i]-'a');
for(int i=1; i<=tot; ++i) ++tm[len[i]];
for(int i=1; i<=n; ++i) tm[i]+=tm[i-1];
for(int i=1; i<=tot; ++i) A[tm[len[i]]--]=i; long long res=0;
for(int i=tot,x=A[i],f; i; x=A[--i])
f=fa[x], res+=1ll*sz[f]*sz[x]*len[f], sz[f]+=sz[x];
printf("%lld\n",1ll*n*(n+1)/2*(n-1)-(res<<1));
}
}sam; int main()
{
sam.Build();
return 0;
}

BZOJ.3238.[AHOI2013]差异(后缀自动机 树形DP/后缀数组 单调栈)的更多相关文章

  1. bzoj 3238&colon; &lbrack;Ahoi2013&rsqb;差异【SAM&plus;树形dp】

    首先只有lcp(i,j)需要考虑 因为SAM的parent树是后缀的前缀的最长公共后缀(--),所以把这个串倒过来建SAM,这样就变成了求两个前缀的最长公共后缀,长度就是这两个前缀在parent树上的 ...

  2. BZOJ 3238&colon; &lbrack;Ahoi2013&rsqb;差异 &lbrack;后缀自动机&rsqb;

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2512  Solved: 1140[Submit][Status ...

  3. bzoj 3238&colon; &lbrack;Ahoi2013&rsqb;差异 -- 后缀数组

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Description Input 一行,一个字符串S Output 一行,一个 ...

  4. BZOJ 3238&colon; &lbrack;Ahoi2013&rsqb;差异 &lbrack;后缀数组 单调栈&rsqb;

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2326  Solved: 1054[Submit][Status ...

  5. bzoj 3238 Ahoi2013 差异

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2357  Solved: 1067[Submit][Status ...

  6. BZOJ 3238&colon; &lbrack;Ahoi2013&rsqb;差异 后缀自动机 树形dp

    http://www.lydsy.com/JudgeOnline/problem.php?id=3238 就算是全局变量,也不要忘记,初始化(吐血). 长得一副lca样,没想到是个树形dp(小丫头还有 ...

  7. BZOJ 3238 &lbrack;Ahoi2013&rsqb;差异(后缀自动机)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3238 [题目大意] 给出一个串,设T[i]表示从第i位开始的后缀, 求sum(len( ...

  8. BZOJ 3238 &lbrack;Ahoi2013&rsqb;差异 ——后缀自动机

    后缀自动机的parent树就是反串的后缀树. 所以只需要反向构建出后缀树,就可以乱搞了. #include <cstdio> #include <cstring> #inclu ...

  9. BZOJ&period;4199&period;&lbrack;NOI2015&rsqb;品酒大会&lpar;后缀自动机 树形DP&rpar;

    BZOJ 洛谷 后缀数组做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 只考虑求极长相同子串,即所有后缀之间的LCP. 而后缀的LCP在后缀树的LCA处.同差异这道题,在每个点处 ...

随机推荐

  1. C&num;与C&plus;&plus;的发展历程第三 - C&num;5&period;0异步编程巅峰

    系列文章目录 1. C#与C++的发展历程第一 - 由C#3.0起 2. C#与C++的发展历程第二 - C#4.0再接再厉 3. C#与C++的发展历程第三 - C#5.0异步编程的巅峰 C#5.0 ...

  2. Unattend&period;xml应答文件制作(WISM)

    将制作好的应答文件unattend.xml拷贝到模板机sysprep目录下,然后在cmd下运行 (unattend.xml文件可自定义名称)   sysprep /generalize /oobe / ...

  3. 计算2的N次方&amp&semi;&amp&semi;计算e

    2的N次方 注意:这里在处理的时候并没有用循环来处理,而是用移位的做法.    n<<4  就是 n*2^4    ,所以在本例中只需要写 1<<time  (time是要求的 ...

  4. hdu 5172 GTY&&num;39&semi;s gay friends

    GTY's gay friends 题意:给n个数和m次查询:(1<n,m<1000,000);之后输入n个数值(1 <= ai <= n):问下面m次查询[L,R]中是否存在 ...

  5. java基础编程练习

    1.编写程序实现对给定的 4 个整数从大到小的顺序排列. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ...

  6. 关于SQL的over partition by 开窗语句在分页和统计中的使用总

    CREATE TABLE OrderInfo( ID INT IDENTITY(1,1) PRIMARY KEY, CustomerID INT NULL, TotalMoney DECIMAL(18 ...

  7. FuelPHP 系列(三) ------ Model 模型

    框架封装好的 model 类有几个,按需继承就好. 有:/fuel/core/classes/model/crud.php /fuel/packages/orm/classes/model.php / ...

  8. CF873B Balanced Substring

    1到n内0,1个数相同的个数的最长字串 \(i>=j\) \[1的个数=0的个数\] \[sum[i]-sum[j-1]=i-(j-1) - (sum[i]-sum[j-1])\] 这里把\(( ...

  9. touch 命令&lpar;转&rpar;

    原文:http://www.cnblogs.com/peida/archive/2012/10/30/2745714.html linux的touch命令不常用,一般在使用make的时候可能会用到,用 ...

  10. alpha-beta搜索算法

    alpha-beta搜索(min-max搜索): 简称mfs,用来解决双方最优决策博弈问题. 核心思想:在搜索树中,下一层越小,对当前层越有利,由于取max,一旦下一层出现了比其他孩子结果更大的值,那 ...