【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是一颗存储多个字符串的树.相邻节点间的边 ...
随机推荐
- SpringBoot集成ActiveMq消息队列实现即时和延迟处理
原文链接:https://blog.csdn.net/My_harbor/article/details/81328727 一.安装ActiveMq 具体安装步骤:自己谷歌去 二.新建springbo ...
- HTTP权威指南-报文与状态码
所有的报文都向下流动 报文流向 报文组成 HTTP方法 状态码 GET示例 HEAD示例 100~199 信息性状态码 200~299 成功状态码 300~399重定向状态码 400~499 客户端错 ...
- Generative Adversarial Network (GAN) - Pytorch版
import os import torch import torchvision import torch.nn as nn from torchvision import transforms f ...
- SpringBoot之分页插件PageHelper的使用
在springboot中使用PageHelper插件有两种较为相似的方式,接下来我就将这两种方式进行总结. 方式一:使用原生的PageHelper 1.在pom.xml中引入依赖 <depend ...
- Scala Map与Tuple
创建Map // 创建一个不可变的Map val ages = Map("Leo" -> 30, "Jen" -> 25, "Jack&q ...
- Windows上安装配置SSH教程(1)
作者:feipeng8848 出处:https://www.cnblogs.com/feipeng8848/p/8559803.html 本站使用「署名 4.0 国际」创作共享协议,转载请在文章明显位 ...
- 前端require代码抽离小技巧
DEMO 文件目录结构 plugin.js // /CommonJS规范 // var exports = module.exports; exports.test = function () { c ...
- 为Visual Studio安装其他控件(cognex 康耐视)时报错:未能加载文件或程序集 EnvDTE, Version=8.0.0.0
解决办法: 在VS的路径下(一般为:C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\Private ...
- Spring/Spring Boot整合Weblogic JMS实战
本文主要介绍weblogic jms的配置,包括JMS 服务器和JMS 模块(连接工厂.队列.远程 SAF 上下文.SAF 导入目的地.SAF 错误处理)的配置:并在Spring/Spring Boo ...
- oracle 根据时间字段查询
oracle 根据时间字段查询数据 ROWNUM 是对前面查询的记录做限制,比如查询的记录 > 2000 条,那么只取前面的 2000 条 ''' SELECT * FROM (SELECT C ...