【bzoj3238】差异 后缀树
题目大意:给你一个字符串$S$,设$S_i$是串$S$第$i$长的后缀,求:
$\sum\limits_{i=1}^{|S|} \sum\limits_{j=i+1}^{|S|} |S_i|+|S_j|-2\times lcp(S_i,S_j)$
其中$lcp(x,y)$表示字符串$x$和字符串$y$的最长公共前缀
数据范围:$|S|≤500000$
最近发现后缀树和$sam$没学好,找一点题来做一做
一道后缀树的板题,我们用$sam$建出后缀树后,直接$dfs$遍历,通过$siz$更新$ans$即可,详情见代码
时间复杂度:$O(|S|)$
#include<bits/stdc++.h>
#define M 1000005
#define L long long
using namespace std; char s[M]={}; struct edge{int u,v,next;}e[M]={}; int head[M]={},use=;
void add(int x,int y,int z){use++;e[use].u=y;e[use].next=head[x];head[x]=use; e[use].v=z;}
L siz[M]={},hh[M]={},n,ans=; namespace sam{
int ch[M][],fa[M],l[M],use=,last=;
void exc(int c){
int p=last,np=++use; l[np]=l[p]+; last=use; hh[np]=;
for(;p&&ch[p][c]==;p=fa[p]) ch[p][c]=np;
if(!p) fa[np]=;
else{
int q=ch[p][c];
if(l[p]+==l[q]) fa[np]=q;
else{
int nq=++use;
l[nq]=l[p]+; fa[nq]=fa[q];
fa[q]=fa[np]=nq;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
for(;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
}
}
}
void build(){
for(int i=;i<=use;i++) add(fa[i],i,l[i]-l[fa[i]]);
}
}; void dfs(int x,int dep){
L sumsq=;
for(int i=head[x];i;i=e[i].next){
dfs(e[i].u,dep+e[i].v);
siz[x]+=siz[e[i].u];
sumsq+=siz[e[i].u]*siz[e[i].u];
}
ans-=(siz[x]*siz[x]-sumsq)*dep;
ans-=hh[x]*dep*siz[x]*;
siz[x]+=hh[x];
} main(){
scanf("%s",s+); n=strlen(s+);
for(int i=n;i;i--) sam::exc(s[i]-'a');
sam::build();
ans=(n-)*(n+)*n/;
dfs(,);
cout<<ans<<endl;
}
【bzoj3238】差异 后缀树的更多相关文章
- BZOJ 3238: [Ahoi2013]差异((单调栈+后缀数组)/(后缀树))
[传送门[(https://www.lydsy.com/JudgeOnline/problem.php?id=3238) 解题思路 首先原式可以把\(len\)那部分直接算出来,然后通过后缀数组求\( ...
- BZOJ 3879: SvT [虚树 后缀树]
传送门 题意: 多次询问,给出一些后缀,求两两之间$LCP$之和 哈哈哈哈哈哈哈竟然$1A$了,刚才还在想如果写不好这道题下节数学就不上了,看来是上天让我上数学课啊 $Suffix\ Virtual\ ...
- BZOJ 3238: [Ahoi2013]差异 [后缀自动机]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2512 Solved: 1140[Submit][Status ...
- 后缀树的线性在线构建-Ukkonen算法
Ukkonen算法是一个非常直观的算法,其思想精妙之处在于不断加字符的过程中,用字符串上的一段区间来表示一条边,并且自动扩展,在需要的时候把边分裂.使用这个算法的好处在于它非常好写,代码很短,并且它是 ...
- 后缀树(suffix tree)
参考: 从前缀树谈到后缀树 后缀树 Suffix Tree-后缀树 字典树(trie树).后缀树 一.前缀树 简述:又名单词查找树,tries树,一种多路树形结构,常用来操作字符串(但不限于字符串), ...
- 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组
涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...
- 后缀树系列一:概念以及实现原理( the Ukkonen algorithm)
首先说明一下后缀树系列一共会有三篇文章,本文先介绍基本概念以及如何线性时间内构件后缀树,第二篇文章会详细介绍怎么实现后缀树(包含实现代码),第三篇会着重谈一谈后缀树的应用. 本文分为三个部分, 首先介 ...
- 【Todo】字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树
另开一文分析字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树. 先来一个汇总, 算法: 本文中提到的字符串匹配算法有:KMP, BM, Horspool, Sunday, BF, ...
- [转载]字典树(trie树)、后缀树
(1)字典树(Trie树) Trie是个简单但实用的数据结构,通常用于实现字典查询.我们做即时响应用户输入的AJAX搜索框时,就是Trie开始.本质上,Trie是一颗存储多个字符串的树.相邻节点间的边 ...
随机推荐
- idea设置创建类的注释模板
打开settings>>Editor>>File and Code Templates>>Includes>>File Header
- SpringBoot之分页插件PageHelper的使用
在springboot中使用PageHelper插件有两种较为相似的方式,接下来我就将这两种方式进行总结. 方式一:使用原生的PageHelper 1.在pom.xml中引入依赖 <depend ...
- Linux shell 中 & && [] [[]] () [] 含义
| 语法:command 1 | command 2 功能:把第一个命令 command 1 执行的结果作为 command 2 的输入传给 command 2 & & 放在启动参数后 ...
- Python13之元组(带上枷锁的列表)
一.元组定义 元组一旦建立,元组内的元素不允许修改和删除,这就是元组和列表最大的区别 当元组中仅有一个元素时,需要将元素后面加上逗号,或者不用括号也可以. tuple1 = (12,3234,5435 ...
- python 之 前端开发(盒子模型、页面布局、浮动、定位、z-index、overflow溢出)
11.312 盒子模型 HTML文档中的每个元素都被比喻成矩形盒子, 盒子模型通过四个边界来描述:margin(外边距),border(边框),padding(内填充),content(内容区域),如 ...
- TCP/IP协议图--TCP/IP基础
1. TCP/IP 的具体含义 从字面意义上讲,有人可能会认为 TCP/IP 是指 TCP 和 IP 两种协议.实际生活当中有时也确实就是指这两种协议.然而在很多情况下,它只是利用 IP 进行通信时所 ...
- WUSTOJ 1319: 球(Java)并查集
题目链接:1319: 球 参考:wustoj 1319 球-wust_tanyao,并查集 并查集系列:WUSTOJ 1346: DARK SOULS(Java)并查集 Description Icy ...
- Android--自定义Dialog style
<style name="dialog" parent="@android:style/Theme.Dialog"> <item name=& ...
- 邮件标准协议:MIME(Multipurpose Internet Mail Extensions)
MIME(多用途互联网邮件扩展)指的是一系列电子邮件技术规范 ,主要包括 RFC 2045~2049 传统的电子邮件只能使用 ASCII 字符,导致非英文字符都不能在电子邮件中使用 而且电子邮件中 ...
- 使用Jenkins的Git Parameter插件来从远程仓库拉取指定目录的内容
更换插件安装源 系统管理---插件管理---高级---升级站点,把默认的插件下载地址换成下面这个: https://mirrors.tuna.tsinghua.edu.cn/jenkins/updat ...