单词检索(search)

\(Description\)

小可可是学校图书馆的管理员,现在他接手了一个十分棘手的任务。

由于学校需要一些材料,校长需要在文章中检索一些信息。校长一共给了小可可N篇文章,每篇文章为一个字符串。现在,校长需要他找到这样的单词,它至少在这N篇文章中的M篇文章里出现过,且单词长度为L。可是,工作量十分庞大,但校长又急需小可可完成这项任务。

现在他向你求助,需要你编写程序完成这项艰巨的任务。

\(Input\)

第1行3个正整数N,M,L,表示文章的数目,单词至少出现在M篇文章中和每个单词的长度。

接下来N行,每行一个字符串,表示一篇文章。

\(Output\)

仅一行,表示满足检索条件的单词数。

\(Sample Input\)

3 2 2

noip

istudycpp

imacppstudent

\(Sample Output\)

5

【样例解释】

这5个单词分别为:st,tu,ud,pp,cp。

\(Data Constraint\)

对于20%的数据有1≤N,M≤10;

对于60%的数据有1≤N,M≤100;

对于100%的数据有1≤N,M≤2000,L≤1000。每篇文章长度不大于1000,均有小写字母组成。

思路

字符串?

既然限定了答案字符的长度,那很容易想到分离字符串,统计出现个数

那就是 \(O(nl)\) 级别的个数,空间可以承受

然后怎么存分离出的字符

如果可以

对于每一篇文章,我们把分离的字符去重(因为答案要求的字符至少在N篇文章中的M篇文章里出现过)

最后合在一起

此时统计出现次数超过 \(M\) 的字符数量就是答案

想想,没有问题

关键是分离

如果把每个字符截取下来,那么一片文章处理的复杂度就是 \(O(|S|l)\)

\(n\) 篇就是 \(O(n|S|l)\) 的,显然不可以承受

然后呢?

正解

既然有了思路,那就直接打吧(也有 \(60\) 分了)

可是,现在是追求正解的时候

思路中的瓶颈在于分离字符

而我们知道要获取一段区间的信息,如果满足可加性,那就可以前缀和维护

字符串?

哦,哈希!

具体方式

对于一个字符串,我们对其进行哈希时,考虑映射成一个数字

一个很巧妙的方法是:把字符本身当做一串数字,一个字符对应权值

从高到低每一位的位权就参考十进制的方法,记作 \(B^{k-1}\)

其中 \(k\) 为第 \(k\) 位,\(B\) 是几进制

因为题中字符串均由小写字母构成

所以设为 \(26\) 进制(不这样也行,哈希映射的方法自己选择)

那么对于一个字符串S,有:

\[H(S) = \sum_{i=1}^{|S|} c_iB^{|S|-i}
\]

截取 S 中后 \(l\) 个字符组成的字符串设为 C',前 \(|S| - l\) 个字符组成的字符串设为 C

\[H(C') = H(S) - H(C) * B^l
\]

于是维护 \(s_i =\sum_{k=1}^i H(|1...k|)\)

双模数,以防万一

代码

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const LL p1 = 1e9 + 7 , p2 = 1e9 + 9 , B = 26;
LL s1[1005] , s2[1005] , b1[1005] , b2[1005];
struct node{
LL x , y;
}d[2000005] , c[2000005];
int cnt , tot , n , m , l , ans;
char ch; inline bool cmp(node a , node b){return (a.x < b.x || (a.x == b.x && a.y < b.y));} int main()
{
scanf("%d%d%d" , &n , &m , &l);
b1[0] = b2[0] = 1;
for(register int i = 1; i <= 1001; i++) b1[i] = b1[i - 1] * B % p1;
for(register int i = 1; i <= 1001; i++) b2[i] = b2[i - 1] * B % p2;
int x;
for(register int i = 1; i <= n; i++)
{
x = 0 , s1[0] = 0 , s2[0] = 0 , cnt = 0;
ch = getchar();
while (ch < 'a' || ch > 'z') ch = getchar();
for(; ch >= 'a' && ch <= 'z'; ch = getchar())
{
x++;
s1[x] = (s1[x - 1] * B % p1 + (ch - 'a' + 1)) % p1;
s2[x] = (s2[x - 1] * B % p2 + (ch - 'a' + 1)) % p2;
if (x >= l)
{
d[++cnt].x = (s1[x] + p1 - s1[x - l] * b1[l] % p1) % p1;
d[cnt].y = (s2[x] + p2 - s2[x - l] * b2[l] % p2) % p2;
}
}
sort(d + 1 , d + cnt + 1 , cmp);
c[++tot] = d[1];
for(register int j = 2; j <= cnt; j++)
if (d[j].x != d[j - 1].x || d[j].y != d[j - 1].y)
c[++tot] = d[j];
}
sort(c + 1 , c + tot + 1 , cmp);
x = 1;
while (x <= tot)
{
int s = 1;
while (c[x].x == c[x + 1].x && c[x].y == c[x + 1].y && x < tot) x++ , s++;
if (s >= m) ans++;
x++;
}
printf("%d" , ans);
}

单词检索(search)的更多相关文章

  1. 英语单词小程序插件 - EdictPlugin-LTS

    1.插件引入 全局app.json配置 "plugins": { "edict-plugin": { "version": "1. ...

  2. 通过trie树实现单词自动补全

    /** * 实现单词补全功能 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #incl ...

  3. 从Search Sort到Join

    发表于<程序员>2015年4月B的一篇文章,在博客归档下.根据杂志社要求,在自己博客发表该文章亦须注明:本文为CSDN编译整理,未经允许不得转载,如需转载请联系market#csdn.ne ...

  4. 告别炼丹,Google Brain提出强化学习助力Neural Architecture Search | ICLR2017

    论文为Google Brain在16年推出的使用强化学习的Neural Architecture Search方法,该方法能够针对数据集搜索构建特定的网络,但需要800卡训练一个月时间.虽然论文的思路 ...

  5. 海量数据处理之Tire树(字典树)

    参考博文:http://blog.csdn.net/v_july_v/article/details/6897097 第一部分.Trie树 1.1.什么是Trie树 Trie树,即字典树,又称单词查找 ...

  6. 搜索系统核心技术概述【1.5w字长文】

    前排提示:本文为综述性文章,梳理搜索相关技术,如寻求前沿应用可简读或略过 搜索引擎介绍 搜索引擎(Search Engine),狭义来讲是基于软件技术开发的互联网数据查询系统,用户通过搜索引擎查询所需 ...

  7. 关于 微软必应词典客户端(pc) 的案例分析

    第一部分 调研,评测 ●评测 bug one 在词典界面中搜完单词后,将鼠标移到英文例句上的单词时,会显示对应的中文翻译,而当移到短语时则不对应中文翻译. bug two 用orc强力取词,查询如上图 ...

  8. ***PHP preg_match正则表达式的使用

    第一,让我们看看两个特别的字符:‘^’和‘$’他们是分别用来匹配字符串的开始和结束,以下分别举例说明 : "^The": 匹配以 "The"开头的字符串; &q ...

  9. Trie树也称字典树

    Trie树 Trie树也称字典树,因为其效率很高,所以在在字符串查找.前缀匹配等中应用很广泛,其高效率是以空间为代价的. 一.Trie树的原理 利用串构建一个字典树,这个字典树保存了串的公共前缀信息, ...

  10. 第四次作业——WORDSEARCH小游戏

    “谁想出来的这么缺德的题目啊!!!!”一个声音在我心中回荡 这个题目很早就在课堂上公布了,我和我的小伙伴都惊呆了! 这是个毛?根本无从下手的感觉 总是觉得这个小游戏不是程序能给出答案的,因为我的第一印 ...

随机推荐

  1. C++编程笔记(通信)(win32平台)

    目录 一.初始化网络库 二.socket套接字 2.1服务端 2.2客户端 三.发送.接收数据 3.1发送 3.2接收数据 四.自定义的结构体 4.1 发送端 4.2接收端 IPV6版本套接字的创建 ...

  2. 监控Kubernetes集群证书过期时间的三种方案

    前言 Kubernetes 中大量用到了证书, 比如 ca证书.以及 kubelet.apiserver.proxy.etcd等组件,还有 kubeconfig 文件. 如果证书过期,轻则无法登录 K ...

  3. Django聚合函数与分组查询

    目录 一:聚合查询 1.聚合函数作用 2.聚合函数查询关键字: 3.聚合函数 4.聚合函数使用 二:分组查询 1.分组查询 2.返回值 3.分组查询关键字 4.分组查询特点 5总结: 三:分组使用 1 ...

  4. uniapp微信小程序内部跳转其他微信小程序

    uniapp小程序内点击某个按钮跳转另外一个小程序连接,具体实现步骤如下: <view class="home-Item" @click="goNativeinde ...

  5. NOIP-2022游寄

    NOIP-2022游寄 Day 1 虽然没有上次去南京CSP-S那么激动,但还是有点小开心的,毕竟能水掉两天课.Phigros重度沉迷患者,推了4个小时的分.坐右前方那哥们好卷,在车上写图论-- JS ...

  6. [论文总结] Genecology and Adaptation of Forest Trees 林木的基因生态学与适应性

    文章目录 介绍 进化的力量 基因学方法 种源试验 短期基因检测实验 表型与遗传估计 差异化 基因学趋势 预测对气候变化的反应 介绍 基因生态学是研究种内遗传变异与环境条件的关系.它揭示了种群适应环境的 ...

  7. [数据分析与可视化] 数据绘图要点2-Y轴的开始与结束

    数据绘图要点2-Y轴的开始与结束 切割或不切割Y轴可能是数据可视化中最具争议的话题之一.基本上,主要问题在于 Y 轴是否应始终从零开始.数据可视化的目的是讲述一个故事,图形表达方式会对可视化讲述的故事 ...

  8. [OpenCV实战]46 在OpenCV下应用图像强度变换实现图像对比度均衡

    本文主要介绍基于图像强度变换算法来实现图像对比度均衡.通过图像对比度均衡能够抑制图像中的无效信息,使图像转换为更符合计算机或人处理分析的形式,以提高图像的视觉价值和使用价值.本文主要通过OpenCV ...

  9. vs code .net core Linux下离线安装Nuget包

    本人第一次使用 vs code在linux下开发.net core项目,由于处于内网,无法通过在线安装,所以在遇见离线安装Nuget包时,耗费了一番功夫,网上也没有相关的,最后还是多个思路结合才解决的 ...

  10. Shell 基本常识

    Shell 进入命令行 启动 shell 常用命令 系统管理命令 处理数据命令 Linux 基础管理命令 用户管理 管理文件系统 软件包管理系统 使用容器管理软件 理解 shell 子 shell 环 ...