洛谷P3370 && 字符串哈希讲解
字符串哈希
寻找长度为n的主串s中的的匹配串T(长度为m)出现的位置或者次数问题属于字符串匹配问题。
朴素(一般)的想法就是从一个字符串的头开始for循环查找,当查找的一个字符与匹配串首字符相同时,往后查找长度为匹配串长度的字符串并一一比对,如果都一样的话,那么答案就加一;
但是往往有些题数据复杂度不允许这么干,于是我们引入字符串哈希这种操作;
具体流程:
滚动哈希,是优化复杂度的核心;
对于一个字符串的哈希值,我们定义哈希函数为H(C)=(c1b^m-1=c2b^m-2....+cmb^0)mod h,
说明:C为一个字符串名称,它由c1c2c3...cm组成,也就是C=c1c2c3c4....cm,其中m为C的长度;
b和h为互质的两个数(b<h),
也就是我们可以把一个字符串看成一个b进制的数(把‘A’看成1,把‘B’看成2...),因为10进制数(such as1234)可以表示成为1*10^3+2*10^2+3*10^1+4,在这里把10换成b就是b进制数的表示方式;因为字符串哈希形成的数可能很大所以要对原数进行取模h。
很多神仙心中可能会有疑问:取模后即使是不同的字符串他们的哈希值也可能相等,那么不同的字符串会有可能得出相同的哈希值,这样答案不就出错了吗?
答案是有可能的。算法错误?!
但是我们可以将可能性降到几乎忽略不计!
因为 仔细想想,是取模运算使哈希拥有了这种可能,只有取到h和b的公倍数时,哈希值才会相等,
但是我们把最小公倍数搞的很大,不就取不到了吗?
那么首先b和h要满足互质,在相近大小下使公倍数尽可能大,然后有意识调高b和h的值,
如果分别去h=1e9+7,b=1e9+9的话,他们最小公倍数就为(1e9+7)*(1e9+9),哈希值相同概率为1/(1e9+7)*(1e9+9),小到没朋友;
(可惜还是有毒瘤小伙伴出毒瘤数据坑害蒟蒻们。。)
不管了。。反正算法就是这样;
在代码实现中,h不必专门取1e9+7后再进行手动缩小操作,只要利用unsigned无符号整形的自然溢出特性,即可实现;
ok!
安利一个关于scanf读入字符串的小知识:
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#define b 97//97是个质数,你也可以取的更大!
using namespace std;
int n,a[],ans=;//ans初始值为1,因为后面在判断时会少一个
char s[];
inline long long hash(char s[]){
int lenc=strlen(s+);
unsigned long long sum[];
sum[]=;
for(int i=;i<=lenc;i++)
sum[i]=sum[i-]*b+(unsigned)(s[i]-'');//哈希值求法
return sum[lenc];
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s",s+);
a[i]=hash(s);//对于每一个字符串求哈希值
}
sort(a+,a++n);
for(int i=;i<=n;i++)
if(a[i]!=a[i-])ans++;
printf("%d",ans);
return ;
}
还有一个惨痛教训:

这是b开成7后碰到了那极小概率的惨痛经历。。。
而且测试点太大无法下载。。。
完结。。
洛谷P3370 && 字符串哈希讲解的更多相关文章
- 洛谷 P3370 字符串哈希 (模板)
<题目链接> <转载于 >>> > 题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共 ...
- 洛谷 P3370 【模板】字符串哈希
洛谷 P3370 [模板]字符串哈希 题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串. 友情提醒:如果真的 ...
- 洛谷P3370 【模板】字符串哈希
P3370 [模板]字符串哈希 143通过 483提交 题目提供者HansBug 标签 难度普及- 提交 讨论 题解 最新讨论 看不出来,这题哪里是哈希了- 题目描述 如题,给定N个字符串(第i个 ...
- 洛谷—— P3370 【模板】字符串哈希
P3370 [模板]字符串哈希 题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串. 友情提醒:如果真的想好好 ...
- 洛谷 P3370 【模板】字符串哈希 (set||map||哈希||字典树(mle)
P3370 [模板]字符串哈希 题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串. #友情提醒:如果真的想好 ...
- 洛谷——P3370 【模板】字符串哈希
题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串. 友情提醒:如果真的想好好练习哈希的话,请自觉,否则请右转 ...
- 题解 洛谷 P3396 【哈希冲突】(根号分治)
根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...
- 洛谷 简单字符串 'P1055ISBN号码' 问题
题目描述如下: 知识点①:char数组与int型数字进行运算时,需要将 char[i]-'0' .比如 char c[5]; int i; for(i=0;i<5;i++) scanf(&quo ...
- 洛谷P1098 字符串的展开【字符串】【模拟】
题目描述 在初赛普及组的“阅读程序写结果”的问题中,我们曾给出一个字符串展开的例子:如果在输入的字符串中,含有类似于“d-h”或者“4-8”的字串,我们就把它当作一种简写,输出时,用连续递增的字母或数 ...
随机推荐
- react 添加代理 proxy
react package.json中proxy的配置如下 "proxy": { "/api/rjwl": { "target": &quo ...
- GO-REDIS的一些高级用法
1. 前言 说到Golang的Redis库,用到最多的恐怕是redigo 和 go-redis.其中 redigo 不支持对集群的访问.本文想聊聊go-redis 2个高级用法 2. 开启对Clust ...
- 已经配置好了的 jmeter + ant 框架
已经配置好了的 jmeter + ant 框架 ,需要自取,避免查找安装攻略时耗费时间 使用前需配置环境变量,阅读文件内安装文档!!! 链接:https://pan.baidu.com/s/1eRz9 ...
- 【PP系列】SAP PP模块工作中心主数据维护
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[PP系列]SAP PP模块工作中心主数据维护 ...
- 支付宝API
1. 业务场景描述:在我们的爱旅行项目中,用户只有报名并且付款之后才能算作参加旅行团成功,因此必须提供快速便捷的支付功能:这里,我们选择了阿里的支付宝api来实现快捷支付,基于此,我们向蚂蚁金服发起申 ...
- ubuntu 16.04 server 扩容(LVM)磁盘
因为发现我的本地server出现磁盘满了的情况 所以进行lvm的扩容 1 查看磁盘情况 df -h 原本发现 /dev/mapper/ubuntu1604--vg-root 这个磁盘满了 所以要进行扩 ...
- VC/MFC中的CComboBox控件使用详解
CComboBox控件详解 CComboBox控件又称作组合框控件,其有三种形态可供选择,1.简单组合框(Simple)2.下拉组合框(Drop-down)3.下拉列表式组合框(Drop-down l ...
- C#追加日志文件
追加日志文件 using System; using System.IO; class DirAppend { public static void Main() { using (StreamWri ...
- [转帖]2018年的新闻: 国内首家!腾讯主导Apache Hadoop新版本发布
国内首家!腾讯主导Apache Hadoop新版本发布 https://blog.csdn.net/weixin_34194317/article/details/88811258 腾讯也挖了很多 ...
- Codeforces 1209D Cow and Snacks
题目大意 有 $n$ 个不同的糖果,从 $1$ 到 $n$ 编号.有 $k$ 个客人.要用糖果招待客人. 对于每个客人,这些糖果中恰有两个是其最爱.第 $i$ 个客人最爱的糖果编号是 $x_i$ 和 ...