CodeForces 1098F. Ж-function
题目简述:给定字符串$s[1 \dots n](n \leq 2 \times 10^5)$,以及$Q \leq 2 \times 10^5$个询问,每个询问有两个参数$1 \leq l \leq r \leq n$,求
$$ \sum_{i=l}^r \operatorname{lcp}(s[l \dots r], s[i \dots r]), $$
其中$\operatorname{lcp}(s, t)$表示字符串$s$和$t$的最长公共前缀(Longest Common Prefix)的长度。
解:
后缀自动机(Suffix Automaton)与后缀树(Suffix Tree)
后缀自动机学习资料:
0. 论文:E. Ukkonen. On-line construction of suffix trees. Algorithmica, 14(3): 249-260 (1995)
1. CSDN
2. SAISUMIT
3. CodeForces
后缀树学习资料:
1. cnblogs
为了方便起见,我们在这里再次简要申明后缀自动机和后缀树的定义,以防止混淆各种不同定义的细微差别。
后缀自动机
一个(确定)有限状态自动机((Deterministic) Finite-State Automaton)$A = (Q, \Sigma, \delta, q_0, F)$,其中
·$Q$是一个有限的状态集合。
·$\Sigma$是一个有限的字符集。
·$\delta: Q \times \Sigma \to Q$是转移函数。若$\delta(p,a)=q$,则可看作是$p$至$q$有一条权值为$a$的边。
·$q_0 \in Q$是初始状态。
·$F \subseteq Q$是接受状态的集合。
一个非空字符串$s$的后缀自动机$\text{SA}(s)$是一个有限状态自动机$A = (Q, \Sigma, \delta, q_0, F)$,其中
·$Q$和$\delta$构成了一个连通的有向无环图(Directed Acyclic Graph)。
·$F = \{ f_1, f_2, \dots, f_{|s|} \}$,其中$f_{k}$对应后缀$s[k\dots |s|]$。若对$q \in Q$,定义$ \text{str}(q) = \{ t \in \Sigma^*: \delta(q_0, t) = q \} $,则$\text{str}(f_k) \supseteq \{ s[k \dots |s|] \}$。
这样,被$\text{SA}(s)$接受的字符串即为$s$的后缀,严格的说,$\mathcal{L}(\text{SA}(s)) = \text{suffix}(s)$,其中$\text{suffix}(s) = \{ s[k \dots |s|]: 1 \leq k \leq |s| \}$。
状态$q$的代表字符串是$\text{str}(q)$中的最长串,为方便起见仍然记作$q$。对任意$q \in Q$,存在$1 \leq k \leq |q|$,使得$\text{str}(q) = \{ q[i\dots |q|]: 1 \leq i \leq k \}$。定义状态$q$的后缀链接(或者称为失败指针)$\text{link}(q)$为$|p|$最长的$p$,使得$p \in \text{suffix}(q)$且$p \notin \text{str}(q)$,即$\text{link}(q) = q[k+1 \dots |q|]$。注意到$|q| > |\text{link}(q)|$,从而$Q$和$\text{link}$构成了一棵有根树,树根为$q_0$,记这棵树为$T(\text{SA}(s))$。
定理:存在$O(n)$算法,对给定字符串$s$,构造其后缀自动机$\text{SA}(s)$。
后缀树
一个非空字符串$s$的后缀树$\text{ST}(s)$是一棵(最简)字典树(Trie),这棵字典树的单词表为$\text{suffix}(s)$,即$s$的所有后缀。$\text{ST}(s)$的每条边上都有$s$的某个子串作为其权值,从而$\text{ST}(s)$每个节点$v$都对应一个$s$的子串(即从根到这个节点路径上所有边权的连接),记作$\text{str}(v)$。每个$s$的后缀$s[k \dots |s|]$都对应$\text{ST}(s)$的一个叶子节点。而每个节点$v$的父节点$w$满足$\text{str}(w)$是$\text{str}(v)$的前缀,且$\text{str}(w)$长度最长。
定理:$T(\text{SA}(s)) = \text{ST}(\text{rev}(s))$,其中$\text{rev}(s)$表示$s$的翻转字符串。
因此,可以通过先构造字符串$\text{rev}(s)$的后缀自动机,来构造$s$的后缀树。(这是因为代码量较短)
问题转化
定义$\text{ST}(s)$中,节点$v$的深度为$\text{depth}(v) = |\text{str}(v)|$。对$1 \leq l \leq |s| = n$,我们把$s[l\dots |s|]$对应的后缀树节点记作$l$,即$\text{str}(l) = s[l \dots n]$。令$L = r-l+1$,则
$$
\begin{aligned}
\sum_{i=l}^r \operatorname{lcp}(s[l \dots r], s[i \dots r])
& = \sum_{k=1}^{L} \operatorname{lcp}(s[l \dots r], s[l+k-1 \dots r]) \\
& = \sum_{k=1}^{L} \min\{\text{depth}(\text{LCA}(l, l+k-1)), L-k+1 \},
\end{aligned}
$$
其中$\text{LCA}(u, v)$表示节点$u$和$v$的最近公共祖先(Least/Lowest Common Ancestor)。令$v(k)$表示节点$v$的祖先中,其父节点深度$< k$的最近祖先,即:若$u = v(k)$,则$\text{depth}(u) \geq k$且$\text{depth}(\text{father}(u)) < k$。令$\text{leaf}(v) \subseteq [n]$表示节点$v$后代中的所有叶子节点,其中$[n] = \{1,2,\dots,n\}$。从而,
$$
\begin{aligned}
& = \sum_{k=1}^L \left| \text{leaf}(l(k)) \cap [l, l+L-k] \right| \\
& = \sum_{k=1}^L \left| \text{leaf}(l(k)) \cap [l+L-k] \right| - \sum_{k=1}^L \left| \text{leaf}(l(k)) \cap [l-1] \right| \\
& = S_2(L, l, l+L) - S_1(L, l, l-1)
\end{aligned}
$$
其中$S_1(L, l, M) = \sum_{k=1}^L \left| \text{leaf}(l(k)) \cap [M] \right|$,$S_2(L, l, M) = \sum_{k=1}^L \left| \text{leaf}(l(k)) \cap [M-k] \right|$。
树链剖分
令$\text{son}(v)$表示节点$v$的所有儿子节点,$\text{size}(v)$表示以节点$v$为根的子树的大小。定义$\text{heavy}(v) = \arg \max_{u \in \text{son}(v)} \text{size}(u)$表示节点$v$具有最大子树的儿子,他们之间的边称为重边,而与其余儿子之间的边称为轻边。
设根节点为$r$,对任意节点$v$,节点$v$到根节点$r$的路径$P = \text{path}(v \to r)$可划分成若干段子路径$P_1, P_2, \dots, P_m$,其中$P_i = \text{path}(x_i \to y_i)$,满足$x_1 = v$,$y_m = r$且$\text{father}(y_{i}) = x_{i+1}$,每段子路径$P_i$都仅由重边组成。我们称$P_1, P_2, \dots, P_m$是路径$P$的剖分。我们把$P_i = (\mathit{belong}_i, \mathit{no}_i, \mathit{len}_i)$记作$(y_i, v, \text{depth}(x_i)-\text{depth}(\text{father}(y_i)))$,表示该路径的根为$\mathit{belong}_i$,是路径$\text{path}(\mathit{no}_i, r)$的一段子路径,且这段路径的长度为$\mathit{len}_i$。
定理:子路径段数$m \leq \lfloor \log_2 |V| \rfloor+1$,其中$|V|$表示节点个数。
记$\text{route}(v)$表示路径$\text{path}(v \to r)$的剖分,记$\text{route}_{\leq L}(v)$表示路径$\text{path}(v \to r)$中深度$\leq L$部分的剖分,即
$$ \text{route}_{\leq L}(v) = \{ (\mathit{belong}, \mathit{no}, \min\{\mathit{len},L-\text{depth}(\text{father}(\mathit{belong}))\}): (\mathit{belong}, \mathit{no}, \mathit{len}) \in \text{route}(v) \land \text{depth}(\text{father}(\mathit{belong}))<L \}. $$
特别地,令$\text{route}_{=L}(v) = \text{route}_{\leq L}(v) - \text{route}_{\leq L-1}(v)$。
计算$S_1(L,l,M)$
于是
$$
\begin{aligned}
S_1(L, l, M)
& = \sum_{k=1}^L \sum_{v = 1}^{M} [v \in \text{leaf}(l(k))] \\
& = \sum_{b} \sum_{k=1}^L \sum_{(b, l, \mathit{len}_q) \in \text{route}_{= k}(l)} \sum_{v=1}^{M} \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [\mathit{len}_q \leq \mathit{len}_p] \\
& = \sum_{(b, l, \mathit{len}_q) \in \text{route}_{\leq L}(l)} \sum_{v=1}^{M} \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} \min\{\mathit{len}_q, \mathit{len}_p\}
\end{aligned}
$$
在固定$b$和$\mathit{len}_q$后,令
$$ a[i] = \sum_{v=1}^M \sum_{(b,v,i)\in\text{route}(v)} 1. $$
则
$$
\begin{aligned}
\sum_{v=1}^{M} \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} \min\{\mathit{len}_q, \mathit{len}_p\}
& = \sum_{i} a[i] \min\{\mathit{len}_q, i\} \\
& = \mathit{len}_q \sum_{i > \mathit{len}_q} a[i] + \sum_{i=1}^{\mathit{len}_q} ia[i],
\end{aligned}
$$
可通过维护$a[i]$的前缀和以及$ia[i]$的前缀和来计算。
我们可以在枚举$b$之后,从小到大枚举$v$(这就是扫描线),并维护$a[i]$及其相关前缀和,当枚举到$v = M$时,可计算$S_1(L,l,M)$在固定$b$后的贡献值。
计算$S_2(L,l,m)$
$$
\begin{aligned}
S_2(L, l, M)
& = \sum_{k=1}^L \sum_{v = 1}^{M-k} [v \in \text{leaf}(l(k))] \\
& = \sum_{b} \sum_{k=1}^L \sum_{(b, l, \mathit{len}_q) \in \text{route}_{\leq k}(l)} \sum_{v=1}^{M-k} \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [\mathit{len}_q \leq \mathit{len}_p] \\
& = \sum_{(b, l, \mathit{len}_q) \in \text{route}_{\leq L}(l)} \sum_{k=1}^{\mathit{len}_q} \sum_{v=1}^n \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [k \leq \mathit{len}_p \land \mathit{pos}_p+k-1 \leq M],
\end{aligned}
$$
其中$\mathit{pos}_p = v+\text{depth}(\text{father}(b))+1$。
固定$b$和$\mathit{len}_q$后,讨论$\mathit{pos}_p+\mathit{len}_p$与$M+1$的大小关系,$S_2(L,l,M)$求和可分为两部分:
$$
\begin{aligned} & \quad \sum_{k=1}^{\mathit{len}_q} \sum_{v=1}^n \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [k \leq \mathit{len}_p \land \mathit{pos}_p+k-1 \leq M] \\
& = \sum_{k=1}^{\mathit{len}_q} \sum_{v=1}^n \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [k \leq \mathit{len}_p \land \mathit{pos}_p+k-1 \leq M \land \mathit{pos}_p+\mathit{len}_p \leq M+1] \\ & \quad + \sum_{k=1}^{\mathit{len}_q} \sum_{v=1}^n \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [k \leq \mathit{len}_p \land \mathit{pos}_p+k-1 \leq M \land \mathit{pos}_p+\mathit{len}_p > M+1] \end{aligned}
$$
Part 1
若$\mathit{pos}_p+\mathit{len}_p \leq M+1$,则条件$\mathit{pos}_p+k-1 \leq M$是冗余的,于是求和可简化为
$$ \begin{aligned} & \quad \sum_{k=1}^{\mathit{len}_q} \sum_{v=1}^n \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [k \leq \mathit{len}_p \land \mathit{pos}_p+k-1 \leq M \land \mathit{pos}_p+\mathit{len}_p \leq M+1] \\ & = \sum_{k=1}^{\mathit{len}_q} \sum_{v=1}^n \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [k \leq \mathit{len}_p \land \mathit{pos}_p+\mathit{len}_p \leq M+1] \\ & = \sum_{v=1}^n \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [\mathit{pos}_p+\mathit{len}_p \leq M+1] \min\{\mathit{len}_q, \mathit{len}_p\} \end{aligned} $$
类似于$S_1$的计算方式,令
$$ a[i] = \sum_{v=1}^n \sum_{(b,v,\mathit{len}_p)\in\text{route}(v)} [\mathit{len}_p+\mathit{pos}_p \leq M+1 \land \mathit{len}_p = i]. $$
则
$$\begin{aligned}
\sum_{v=1}^n \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [\mathit{pos}_p+\mathit{len}_p \leq M+1] \min\{\mathit{len}_q, \mathit{len}_p\}
& = \sum_{i} a[i] \min\{\mathit{len}_q, i\} \\
& = \mathit{len}_q \sum_{i > \mathit{len}_q} a[i] + \sum_{i=1}^{\mathit{len}_q} ia[i],
\end{aligned}$$
我们以$\mathit{pos}_p+\mathit{len}_p$从小到大做扫描线,维护$a[i]$及其相关前缀和,当枚举到$\mathit{pos}_p+\mathit{len}_p = M+1$时,可计算 Part 1 的贡献值。
Part 2
若$\mathit{pos}_p+\mathit{len}_p > M+1$,则$1+\mathit{pos}_p \leq k+\mathit{pos}_p \leq M+1 < \mathit{len}_p+\mathit{pos}_p$。
$$
\begin{aligned}
& \quad \sum_{k=1}^{\mathit{len}_q} \sum_{v=1}^n \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [k \leq \mathit{len}_p \land \mathit{pos}_p+k-1 \leq M \land \mathit{pos}_p+\mathit{len}_p > M+1] \\
& = \sum_{k=1}^{\mathit{len}_q} \sum_{v=1}^n \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [1+\mathit{pos}_p \leq k+\mathit{pos}_p \leq M+1 \land \mathit{pos}_p+\mathit{len}_p > M+1] \\
& = \sum_{k=1}^{\mathit{len}_q} \sum_{v=1}^n \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [\mathit{pos}_p \leq M-k+1 \land \mathit{pos}_p+\mathit{len}_p > M+1]
\end{aligned}
$$
令
$$ a[i] = \sum_{v=1}^n \sum_{(b,v,\mathit{len}_p)\in\text{route}(v)} [\mathit{len}_p+\mathit{pos}_p > M+1 \land \mathit{pos}_p = i]. $$
则
$$
\begin{aligned}
& \quad \sum_{k=1}^{\mathit{len}_q} \sum_{v=1}^n \sum_{(b, v, \mathit{len}_p) \in \text{route}(v)} [\mathit{pos}_p \leq M-k+1 \land \mathit{pos}_p+\mathit{len}_p > M+1] \\
& = \sum_{k=1}^{\mathit{len}_q} s[M-k+1] \\
& = \mathit{len}_q s[M-\mathit{len}_q+1] + (M+1) (s[M]-s[M-\mathit{len}_q+1]) - (t[M]-t[M-\mathit{len}_q+1]),
\end{aligned}
$$
其中$s[i] = a[1]+\dots+a[i], t[i] = a[1]+2a[2]+\dots+ia[i]$。
我们以$\mathit{pos}_p+\mathit{len}_p$从大到小做扫描线,维护$a[i]$及其相关前缀和,当枚举到$\mathit{pos}_p+\mathit{len}_p = M+2$时,可计算 Part 2 的贡献值。
时间复杂度
设字符串$s$的长度为$|s| = n$,构建后缀树的时间为$O(n)$。根据树链剖分,子问题一共有$O((n+q) \log n)$个,每个子问题需要离线做扫描线利用树状数组求解,故总的时间复杂度为$O((n+q)\log^2 n)$。
CodeForces 1098F. Ж-function的更多相关文章
- Codeforces 429D Tricky Function(平面最近点对)
题目链接 Tricky Function $f(i, j) = (i - j)^{2} + (s[i] - s[j])^{2}$ 把$(i, s[i])$塞到平面直角坐标系里,于是转化成了平面最近点 ...
- Codeforces(429D - Tricky Function)近期点对问题
D. Tricky Function time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- Codeforces 429D Tricky Function 近期点对
题目链接:点击打开链接 暴力出奇迹. 正解应该是近期点对.以i点为x轴,sum[i](前缀和)为y轴,求随意两点间的距离. 先来个科学的暴力代码: #include<stdio.h> #i ...
- 通过百度echarts实现数据图表展示功能
现在我们在工作中,在开发中都会或多或少的用到图表统计数据显示给用户.通过图表可以很直观的,直接的将数据呈现出来.这里我就介绍说一下利用百度开源的echarts图表技术实现的具体功能. 1.对于不太理解 ...
- Educational Codeforces Round 13 D:Iterated Linear Function(数论)
http://codeforces.com/contest/678/problem/D D. Iterated Linear Function Consider a linear function f ...
- Codeforces Gym 100187M M. Heaviside Function two pointer
M. Heaviside Function Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/ ...
- Codeforces Round #245 (Div. 1) 429D - Tricky Function 最近点对
D. Tricky Function Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 codeforces.com/problemset/problem/42 ...
- Codeforces Round #277 (Div. 2) A. Calculating Function 水题
A. Calculating Function Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/4 ...
- Codeforces 837E. Vasya's Function
http://codeforces.com/problemset/problem/837/E 题意: f(a, 0) = 0; f(a, b) = 1 + f(a, b - gcd(a, b)) ...
随机推荐
- Excel应用----制作二级下拉菜单【转】
应用: 原始数据源是两列的源数据,那该如何制作二级下拉菜单, 当然可以将这两列的数据源,转换成上面的那种格式,再用上面的方法来制作. 今天教大学的方法是直接通过这种两列式的数据源来制作下拉菜单,如果A ...
- Linq实现SQL in
比如 Id in (1,2,3) int[] a={1,2,3}; list.Where(x=>a.Contains(x.Id))
- web前端面试系列 - js中的prototype
js中一切皆为对象,其中函数也是一种对象, 而每个函数都有一个prototype属性,其值也是一个对象. 一.prototype的作用 1. 在多个实例对象之间共享数据和方法. 2. 通过原型链实现继 ...
- What is the relationship between Xcode, Swift and Cocoa?
Xcode is an IDE for developing Swift or Objective-C applications, which can use the Cocoa API (which ...
- iOS移动开发周报-第18期
iOS移动开发周报_18期 [摘要]:本期iOS移动开发周报带来如下内容:苹果与 IBM 展开长期深度合作,Swift官方博客,Swift开发的视频教程等. 新闻 <苹果与 IBM 展开长期深度 ...
- 官网下载kettle
首先什么是kettle,引用下百度百科 Kettle是一款国外开源的ETL工具,纯java编写,可以在Window.Linux.Unix上运行,数据抽取高效稳定. Kettle 中文名称叫水壶,该项目 ...
- 不为客户连接创建子进程的并发回射服务器( poll实现 )
前言 在上文中,我使用select函数实现了不为客户连接创建子进程的并发回射服务器( 点此进入 ).但其中有个细节确实有点麻烦,那就是还得设置一个client数组用来标记select监听描述符集中被设 ...
- FormsAuthentication 在asp.net MVC中的应用
说明:开发环境 vs2012 asp.net mvc4 c# 项目结构: 1.开发步骤 1.1 创建项目 打开vs2012 开发环境 “文件”--“新建”--“项目” 选择asp.net mvc项目类 ...
- html5 file 上传图片
说明:开发环境 vs2012 mvc4项目,后台语言csharp 1.前端代码 <html xmlns="http://www.w3.org/1999/xhtml"> ...
- AndroidPageObjectTest_Simple.java
以下代码使用ApiDemos-debug.apk进行测试 //这个脚本用于演示PageFactory的功能:使用注解@FindBy.@AndroidFindBy.@IOSFindBy定位元素.注解用法 ...