首页 > 其他分享 >后缀数组好题选讲

后缀数组好题选讲

时间:2024-01-31 22:25:05浏览次数:28  
标签:dots geq 后缀 text 选讲 好题 leq rk

CodeForces 616F Expensive Strings

https://codeforces.com/problemset/problem/616/F

Problem tags

  • string suffix structures
  • strings
  • *2700

Problem Statement

给定 \(n\) 个字符串 \(t_1, t_2, \dots, t_n\)。每个字符串有一个权值,对于 \(1 \leq i \leq n\),有 \(t_i\) 的权值为 \(c_i\)。定义一个字符串 \(s\) 的价值为:

\[f(s) = |s|\sum_{i = 1}^{n}c_i \times appear(t_i, s) \]

其中 \(|s|\) 表示 \(s\) 的长度,\(appear(t_i, s)\) 表示 \(s\) 在 \(t_i\) 中作为子串出现的次数。

求 \(f(s)\) 的最大值,要求 \(|s| > 0\)。

Constraints

  • \(1 \leq n \leq 10^5\)
  • \(\displaystyle \sum_{i = 1}^{n}|t_i| \leq 5 \times 10^5\)
  • \(\displaystyle \sum_{i = 1}^{n}\sum_{j = 1}^{|t_i|}[t_{i, j} \in \{\text{a, b, c, }\dots\text{, z}\}] = \sum_{i = 1}^{n}|t_i|\)
  • \(-10^7 \leq c_i \leq 10^7\)

Solution & Code

考虑把 \(t_1, t_2, \dots, t_n\) 拼成一个大字符串 \(T\),用 互不相同 的分隔符分开(分隔符不能是小写字母)并建立后缀数组。

考虑统计 \(s\) 在 \(t_1, t_2, \dots, t_n\) 中作为子串的所有出现。发现只需要统计 \(s\) 在 \(T\) 中的所有作为子串的出现即可。考虑统计 \(|s| = k\) 的答案,我们只需要 \(\text{LCP}(T[x \sim |T|], T[y \sim |T|]) \geq k\),发现需要的是 \(\displaystyle \min_{\min(rk_x, rk_y) + 1}^{\max(rk_x, rk_y)}height_i \geq k\),也就是对于所有的 \(\min(rk_x, rk_y) < i \leq \max(rk_x, rk_y)\),有 \(height_i \geq k\),考虑建图,如果 \(height_u \geq k\),那么就在 \(u - 1\) 和 \(u\) 之间连一条边,意思就是 \(rk = u - 1\) 的后缀和 \(rk = u\) 的后缀的 \(\text{LCP}\geq k\)。所以 \(\text{LCP}(T[x \sim |T|], T[y \sim |T|]) \geq k\) 当且仅当 \(rk_x\) 和 \(rk_y\) 在图中连通,一个连通块内的拥有一个长度为 \(k\) 的 \(\text{LCP}\),只需要用并查集维护权值即可,然后更新答案。至于具体如何建图,只需要倒序枚举 \(\text{LCP}\) 的长度,然后按 \(height\) 数组的具体值建图即可,具体见代码。记得答案对 \(f(t_1), f(t_2), \dots, f(t_n), f(\text{a}), f(\text{b}), \dots, f(\text{z})\) 取个 max,时间复杂度瓶颈在建立后缀数组/dx,为 \(O(n \log^2 n)\)。

Warning:答案的下界为 \(0\),你可以构造一个足够大的字符串然后不在任何一个字符串内作为子串出现!!!

代码:https://codeforces.com/contest/616/submission/244267521

标签:dots,geq,后缀,text,选讲,好题,leq,rk
From: https://www.cnblogs.com/RB16B/p/18000253

相关文章

  • 后缀数组小计
    0前言被迫上班了属于是前置知识倍增基数排序基数排序这个很好理解举个例子:对\(n\)对二元组\((x,y)\)排序优先比较关键字\(x\)相同再比较关键字\(y\)第一步:以\(y\)为基准从小到大把所有二元组排序得到\(y\)递增的序列第二部:以\(x\)为基准从小到大......
  • 后缀数组
    后缀数组定义suf[i]i到最后的子串rank[i]suf[i]在所有后缀中的排名sa[i]排名为i的后缀的开始位置sa[i]与rank[i]为互逆操作,相反的排列height[i]suf[sa[i]]与suf[sa[i-1]]的最长公共前缀H[i]即Height[rank[i]]求SA的倍增算法用基数排序,排序次数为\(\lceil......
  • 通信(二分+SPFA好题)
    第1题    通信查看测评数据信息某城市有N座通信基站,P条双向电缆,第i条电缆连接基站Ai和Bi。特别地,1号基站是通信公司的总站,N号基站位于一座农场中。现在,农场主希望对通信线路进行升级,其中升级第i条电缆需要花费Li。电话公司正在举行优惠活动。农场主可以指定......
  • 【板子】后缀自动机(SAM)
    //lg3804//Copyrightyeyou26//注意:这道题不是纯纯的后缀自动机,main函数有一点额外处理#include<bits/stdc++.h>usingnamespacestd;#definelllonglong#defineN(int(2e6+6))intfa[N];intch[N][28];intlen[N];intcnt[N];llans;intidx=1;intnp=1;str......
  • 01.23 算法补全:后缀数组
    秉着技多不压身的想法,我认为在有些时候后缀数组的直接建法还是有用处的,于是决定快速地补一下这个算法。以后看看能不能每天稳定产出一篇,随便什么的文章。可能是一个trick的记录,也能是算法补全,或者是题解慢报/速报,亦或是鲜花。这些内容会同步发表于我的洛谷blog:https://www.luo......
  • BZOJ1717 Milk Patterns 产奶的模式 (二分+后缀数组+height数组)
    发现这样起标题更能引流(ylg实锤了)题意给定一个长度为\(n\)的数组\(a\),求在\(a\)中出现了至少\(k\)次的最长子串的长度。解法考虑将一个子串拆成两个后缀,即\([l,r]=[l,n]-[r,n]\),发现一个长度为\(x\)的子串\(t\)在\(i,j\)两个位置出现过当且仅当后缀\(i,j\)有......
  • 【学习笔记】后缀自动机 SAM
    一.后缀自动机的定义SAM(SuffixAutomaton)是一种有限状态自动机,仅可以接受一个字符串的所有后缀。如果您不懂自动机,那么换句话说:SAM是一个有向无环图。称每个结点为状态,边为状态间的转移,每个转移标有一个字母,同一节点引出的转移不同。SAM存在一个源点\(S\),称为初始状态......
  • 数论好题 CF900D
    前置推导令\(b_1=\frac{a_1}{x},b_2=\frac{a_2}{x},\dots,b_n=\frac{a_n}{x}\)。很显然\(b_i\)为整数,且\(b\)数组的全部元素互质,即\(gcd(b_1,b_2,b_3,\dots,b_n)=1\)。因为\[\sum_{i=1}^{n}a_i=y\]所以\[x\times\sum_{i=1}^{n}b_i=y\]\[\sum_{i=......
  • 数论好题 CF900D
    前置推导令\(b_1=\frac{a_1}{x},b_2=\frac{a_2}{x},\dots,b_n=\frac{a_n}{x}\)。很显然\(b_i\)为整数,且\(b\)数组的全部元素互质,即\(gcd(b_1,b_2,b_3,\dots,b_n)=1\)。因为\[\sum_{i=1}^{n}a_i=y\]所以\[x\times\sum_{i=1}^{n}b_i=y\]\[\sum_{i=......
  • 后缀数组 SA 学习笔记
    后缀数组SA学习笔记后缀数组处理字符串后缀排名,公共子串类问题十分优秀,可以在部分情况下替代后缀自动机(SAM),本文主要讲解后缀数组的实现过程和部分例题。正文定义后缀:从\(i\)开始到字符串结束的一个特殊子串,本文用\(suf(i)\)表示从\(i\)开始的后缀。后缀数组SA:SA是......