Processing math: 100%

YZOJ P3750 [校内训练20180529]字符串的频度

YZOJ P3750 [校内训练20180529]字符串的频度

时间限制:1000MS      内存限制:524288KB

出题人:zzx          难度:6.0

  • 题目描述

给定字符串 s 。你需要回答 n 个询问,第 i 个询问给出一个正整数 k_i 和一个字符串 m_i,请求出 s 的所有子串 t 中,满足 m_it 中出现至少 k_i 次的字符串 t 的长度的最小值。

一个字符串的子串是该字符串中的连续一段字符。

保证任意两个询问的 m_i 不相同。

  • 输入格式

第一行包含一个字符串 s1 \leq \left|s\right| \leq 10^5)。

第二行包含一个正整数 n1 \leq n \leq 10^5)。

接下来 n 行,每行一个正整数 k_i1 \leq k_i \leq \left|s\right|)和一个非空字符串 m_i,表示第 i 个询问。

所有字符串仅包含小写英文字母,且所有询问字符串的总长度不超过 10^5

  • 输出格式

对于每个字符串输出一行表示答案。

如果 m_is 中出现次数小于 k_i,输出 -1

  • 样例输入

  • 样例输出

  • 子任务

测试点编号 |s| n 约定
1-3 \le 300 \le 300
4-5 \le 5000 \le 5000
6-7 \le 100000 \le 100000 字符串 s 仅包含字符 a
8-10 \le 50000 \le 50000 每个 m_is 中出现次数不超过 50
11-12 \le 100000 \le 100000
13-16 \le 50000 \le 50000 所有 m_i 的总长不超过 50000
17-20 \le 100000 \le 100000

 

 

 


 

 

题解的做法:

将所有的匹配串建一个 AC自动机,然后母串放在上面跑,经过的点计入下当前母串所匹配到的位置,用 fail指针在树上启发式合并,对树上所有的匹配串的终止点计算答案,计算答案是与匹配串在母串出现次数线性相关的。

证明该算法总复杂度是 O(nlog^2n+n\sqrt n)

复杂度的关键在于证明 所有匹配串在母串出现次数之和 范围有保证。

题目中保证任意的串 m_i 均不相同,所以长度大于 \sqrt n 最多只能出现 \sqrt n 次,长度小于 \sqrt ns 的子串在母串出现次数之和最多就 n\sqrt n,所以所有匹配串在母串出现次数之和为 O(n\sqrt n)

 

首先建 AC自动机是肯定的,但是我们有一个很好的 动态 线性表: std::vector<> !!!

所以匹配到一个串就暴力插到 std::vector<>  里,最后在里面暴力找。

时空复杂度 O(n\sqrt n)

 

 

 

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注