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处.同差异这道题,在每个点处 ...
随机推荐
- freeRTOS中文实用教程3--中断管理之中断服务例程中使用队列
1.前言 消息队列不仅可以用于事件通信,还可以用来传递数据 2.实例说明消息队列的执行过程 3.主要API API名称 说明 参数 返回值 xQueueSendFromISR()完全等同于 xQueu ...
- jvm系列二、JVM内存结构
原文链接:http://www.cnblogs.com/ityouknow/p/5610232.html 所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemory ...
- git免密配置
1.在git安装目录下双击bash.exeC:\DevTools\Git\bin 2.在弹出窗口内输入,回车,回车ssh-keygen -t rsa -C "542113457@qq.com ...
- Java快速学习笔记01
这一波快速学习主要是应付校招笔面试用,功利性质不可避免. 学习网址: http://www.runoob.com/java/java-tutorial.html 执行命令解析: 以上我们使用了两个命令 ...
- python实现简单登陆流程
登陆流程图: 代码实现: #-*- coding=utf-8 -*- import os,sys,getpass ''' user.txt 格式 账号 密码 是否锁定 错误次数 jack 123 un ...
- sqlserver2008r2数据库关联孤立账号的方法
重新安装mssql数据库后可能有这样的问题, 在数据还原到其他服务器时,登录名会丢失,重建非常麻烦 特別是数据库用户较多的的情况,其实这个问题解决非常简单, sql serve ...
- 通达OA2008优化前端web为lnmp环境及后续优化
1.安装lnmp环境 具体参考:CentOS6.5编译安装Nginx1.8.1+MySQL5.5.48+PHP5.2.17+xcache3.2+ZendOptimizer-3.3.9 http://b ...
- centos6.5报错:checking filesystems failed问题处理
centos系统重启报错:checking filesystems failed checking filesystems /dev/mapper/vg_0-root: 搜了下可能是文件系统损坏 根据 ...
- centos6下的lvm逻辑卷的管理
LVM:Logical Volume Manager 将多块设备组合成一个来使用 dm:device mapper 设备映射 设备文件 /dev/卷组名/逻辑卷名 /dev/mapp ...
- [学习笔记]Java代码中各种类型变量的内存分配机制
程序运行时,我们最好对数据保存到什么地方做到心中有数.特别要注意的是内存的分配.有六个地方都可以保存数据: (1) 寄存器 这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处理器内部.然而 ...