【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是一颗存储多个字符串的树.相邻节点间的边 ...
随机推荐
- 《ucore lab6》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1: 使用 Round Robin 调度算法(不需要编码) 题目 完成练习0后,建议大家比较一下(可用kdiff3等文件比较软件) 个人完成 ...
- 039 Android ShareSDK实现分享功能
1.参考文献: https://blog.csdn.net/augfun/article/details/86551294 http://wiki.mob.com/sdk-share-android- ...
- [转帖]微软 SQ1 参数一览:8 核 Kryo 495,Adreno 685 GPU
微软 SQ1 参数一览:8 核 Kryo 495,Adreno 685 GPU http://www.myzaker.com/article/5d989ef68e9f0977765e5506/ 微软发 ...
- Quartz.Net—DateBuilder
定时框架中最重要的就是时间,我们也可以直接使用Cron这种事件格式. 使用其他的时间格式,就可以用DateBuilder快速的创建出需要的时间. 因为quartz是一个定时框架,所以对于操控时间 ...
- git config命令详解
Git有一个工具被称为git config,它允许你获得和设置配置变量:这些变量可以控制Git的外观和操作的各个方面. 一. 配置文件的存储位置 这些变量可以被存储在三个不同的位置: 1./etc/ ...
- C++语法笔记(上)
客观事物中任何一个事物都可以看成一个对象,对象是由一组属性和一组行为构成的. c++中,每个对象都是由数据与函数这两部分构成,数据就是对象的属性,函数就是对象的行为. c++中对象的类型称为类,类是一 ...
- 织梦/dedecms采集怎么去除a标签
dedecms采集去除a标签代码 DedeCMS采集规则-过滤-替换-技巧2009-01-14 15:491.采集去除链接[Copy to clipboard]CODE:{dede:trim}]*)& ...
- Asp.net Identity 修改默认数据库,增加自定义字段
visual studio 2013 先新建一个项目 选择MVC,确定 打开 Views\Shared\_Layout.cshtml文件,按自己的要求修改 改 <!DOCTYPE html> ...
- 正整数序列 Help the needed for Dexter ,UVa 11384
题目描述 Description 给定正整数n,你的任务是用最少的操作次数把序列1, 2, …, n中的所有数都变成0.每次操作可从序列中选择一个或多个整数,同时减去一个相同的正整数.比如,1,2,3 ...
- js 遍历树的层级关系的实现
1.遍历树的层级关系 1)先整理数据 2)找到id和数据的映射关系 3)然后找到父节点的数据,进行存储 test() { const list = [ { id: ", parentId: ...