BZOJ.3238.[AHOI2013]差异(后缀自动机 树形DP/后缀数组 单调栈)
\(Description\)
.jpg)
\(Solution\)
len(Ti)+len(Tj)可以直接算出来,每个小于n的长度会被计算n-1次。
\]
对于后半部分:
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/后缀数组 单调栈)的更多相关文章
- bzoj 3238: [Ahoi2013]差异【SAM+树形dp】
首先只有lcp(i,j)需要考虑 因为SAM的parent树是后缀的前缀的最长公共后缀(--),所以把这个串倒过来建SAM,这样就变成了求两个前缀的最长公共后缀,长度就是这两个前缀在parent树上的 ...
- BZOJ 3238: [Ahoi2013]差异 [后缀自动机]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2512 Solved: 1140[Submit][Status ...
- bzoj 3238: [Ahoi2013]差异 -- 后缀数组
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 一行,一个字符串S Output 一行,一个 ...
- BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1054[Submit][Status ...
- bzoj 3238 Ahoi2013 差异
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2357 Solved: 1067[Submit][Status ...
- BZOJ 3238: [Ahoi2013]差异 后缀自动机 树形dp
http://www.lydsy.com/JudgeOnline/problem.php?id=3238 就算是全局变量,也不要忘记,初始化(吐血). 长得一副lca样,没想到是个树形dp(小丫头还有 ...
- BZOJ 3238 [Ahoi2013]差异(后缀自动机)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3238 [题目大意] 给出一个串,设T[i]表示从第i位开始的后缀, 求sum(len( ...
- BZOJ 3238 [Ahoi2013]差异 ——后缀自动机
后缀自动机的parent树就是反串的后缀树. 所以只需要反向构建出后缀树,就可以乱搞了. #include <cstdio> #include <cstring> #inclu ...
- BZOJ.4199.[NOI2015]品酒大会(后缀自动机 树形DP)
BZOJ 洛谷 后缀数组做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 只考虑求极长相同子串,即所有后缀之间的LCP. 而后缀的LCP在后缀树的LCA处.同差异这道题,在每个点处 ...
随机推荐
- mysql服务里面没有启动项
解决:5.0版本:开始->运行->cmd,进到mysql安装的bin目录D:\MySQL\bin>mysqld.exe -installService successfully in ...
- ARMV8 datasheet学习笔记4:AArch64系统级体系结构之编程模型(4)- 其它
1. 前言 2.可配置的指令使能/禁用控制和trap控制 指令使能/禁用 当指令被禁用,则这条指令就会变成未定义 指令Trap控制 控制某条或某些指令在运行时进入陷阱,进入陷阱的指令会产生trap异常 ...
- JDK8 Lambda表达式对代码的简化
只是举个例子: public class LambdaDemo { public static String findData( String name , LambdaInterface finde ...
- ansible报错Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this
安装和配置好ansible,执行命令时报错如下 [root@test01 ansible-install]# ansible test -m shell -a 'w' >> Using a ...
- 最新 macOS Sierra 10.12.3 安装CocoaPods及使用详解
一.什么是CocoaPods 每种语言发展到一个阶段,就会出现相应的依赖管理工具,例如 Java 语言的 Maven,nodejs 的 npm.随着 iOS 开发者的增多,业界也出现了为 iOS 程序 ...
- kerberos介绍
重要术语 1. KDC 全称:key distributed center 作用:整个安全认证过程的票据生成管理服务,其中包含两个服务,AS和TGS 2. AS 全称:authentication s ...
- PhpStrom添加调试功能
要给PhpStrom添加调试功能,需要安装Xdebug,网址:https://xdebug.org/ 1.如何下载对应thinkphp版本号的Xdebug呢 创建一个php文件,在里面输入phpinf ...
- MyEclipse 2015反编译插件安装
本文转自 MyEclipse 2015反编译插件安装 分享一下下载插件的地址,百度网盘:链接:http://pan.baidu.com/s/1nturiAH 密码:yk73 其次:我来说下具体操作步骤 ...
- Laravel Cache 缓存钉钉微应用的 Access Token
钉钉微应用的 Access token 如何获取? Access_Token 是企业访问钉钉开放平台全局接口的唯一凭证,即调用接口时需携带Access_Token.从接口列表看,所有接口都需要携带 a ...
- poj2279 线性dp
#include<iostream> #include<cstdio> #include<cstring> #define ll long long using n ...