【テンプレート】字符串hash
不懂hash是什么的盆友给出直通车:滴滴滴,开车啦~
如果你看懂了的话:
hash模板来也~
#include <cstdio>
#include <string>
#include <iostream>
#include <algorithm> using namespace std; typedef long long LL; const int N = 1e5 + ; //
const int D = ; //质数
const int MD = 1e9 + ; //大质数 int n;
string s; unsigned long long f[N], g[N]; //g[i]为D的i次方 void prehash(int n) //进行预处理
{
// 预处理时,注意到数字可能很大,对一个数 MD 取模
f[] = s[];//预处理前缀和(进行强制类型转)
for(int i=; i<=n; i++)
f[i] = (1LL * f[i-] * D + s[i-]) % MD; g[] = ; //预处理D
for(int i=; i<=n; i++)
g[i] = 1LL * g[i-] * D % MD;
} int hash(int l, int r) //计算区间 [l,r] 的哈希值
{
int a = f[r];
int b = 1LL * f[l-] * g[r-l+] % MD; return (a - b + MD) % MD; //+MD是为了防止出现负数
} int main()
{
cin >> s;
n = s.length();
prehash(n); while(!cin.eof())//直至按ctrl+z键退出!
{
int l, r;
cin >> l >> r;
cout << s.substr(l-, r-l+) << ": " << hash(l, r) << endl;
//从l-1到r-l+1的字符
} return ;
}
良心推荐洛谷练手题:
1.P3370【模板】字符串哈希
题目描述
如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字、大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串。
友情提醒:如果真的想好好练习哈希的话,请自觉,否则请右转PJ试炼场:)
输入输出格式
输入格式:
第一行包含一个整数N,为字符串的个数。
接下来N行每行包含一个字符串,为所提供的字符串。
输出格式:
输出包含一行,包含一个整数,为不同的字符串个数。
输入输出样例
5
abc
aaaa
abc
abcc
12345
4
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=10,Mi≈6,Mmax<=15;
对于70%的数据:N<=1000,Mi≈100,Mmax<=150
对于100%的数据:N<=10000,Mi≈1000,Mmax<=1500
样例说明:
样例中第一个字符串(abc)和第三个字符串(abc)是一样的,所以所提供字符串的集合为{aaaa,abc,abcc,12345},故共计4个不同的字符串。
Tip: 感兴趣的话,你们可以先看一看以下三题:
BZOJ3097:http://www.lydsy.com/JudgeOnline/problem.php?id=3097
BZOJ3098:http://www.lydsy.com/JudgeOnline/problem.php?id=3098
BZOJ3099:http://www.lydsy.com/JudgeOnline/problem.php?id=3099
如果你仔细研究过了(或者至少仔细看过AC人数的话),我想你一定会明白字符串哈希的正确姿势的^_^
思路:
题解里面是有很多种方法的,但是我认为能够搞懂一种就已经很不错了……
所以我给出的思路就是用set来进行统计,set只能够允许一种数字出现一次,所以我们就可以将给出的字符串的hash值求出来
然后加入到set里面,最后直接输出set里面有多少数就行啦~
PS:
定义函数的时候不要用"hash"这个名字,在洛谷里是关键字!!!
上代码=u=:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <set> using namespace std; typedef unsigned long long ull;
typedef long long LL;
set<ull>ssr; const int N = ;
const int D = ; //质数
const ull MD= 1e9 + ; //大质数 LL n,len;
string s; ull f[N];//预处理前缀和
ull g[N];//预处理 D的i次方 int yuchuli(int q)
{
memset(f,,sizeof(f));
memset(g,,sizeof(g));
f[]=s[];
for(int i=;i<=q;i++)
f[i] = (1LL * f[i-] * D +s[i-]) % MD;
g[]=;
for(int i=;i<=q;i++)
g[i] = 1LL * g[i-] * D % MD;
} int hashs(int l,int r)
{
ull a = f[r];
ull b = 1LL * f[l-] *g[r-l+] % MD; return (a - b + MD) % MD;
} int main()
{
cin>>n;
while(n--)
{
cin>>s;
len=s.length();
yuchuli(len);
ull qq = hashs(,len);
ssr.insert(qq);
}
cout<<ssr.size();
return ;
}
2.
cogs249. [POI2000] 最长公共子串
★★★ 输入文件:pow.in
输出文件:pow.out
简单对比
时间限制:1 s 内存限制:256 MB
给出几个由小写字母构成的单词,求它们最长的公共子串的长度。
任务
- 从文件中读入单词
- 计算最长公共子串的长度
- 输出结果到文件
输入
文件的第一行是整数 n,1<=n<=5,表示单词的数量。接下来n行每行一个单词,只由小写字母组成,单词的长度至少为1,最大为2000。
输出:
仅一行,一个整数,最长公共子串的长度。
样例输入:
3
abcb
bca
acbc
样例输出:
2
思路:
正解据说是后缀数组呢!后缀数组是什么鬼???我又不会...只好胡乱搞hash啦~结果一搞...奇迹的就WA了一个点,结果又胡乱改了一下Mod,然后就A了...真不可思议w
Ps:脑洞产物(正解xxx),能不能过全看 your rp!!!
话不多说:
hash的思路:
- pre:
首先话不多说,跟普通hash一样把每一个单词的hash值求一下,然后快乐地开始进行二分公共子串的长度
- 结束条件:
- 时间复杂度:
坑点:
上代码=v=:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define INF 0x7fffffff
#define LL long long
using namespace std; const int D = ;
const int Mod = ;
const int N = ;
const int le = ;
int n,minl,ans;
LL f[N][le],g[le];
int len[N];
char str[le];
int vis[Mod+],times[Mod+]; bool check(int x)
{
memset(vis,,sizeof(vis));
memset(times,,sizeof(times));
LL cv=g[x];
for(int i=;i<=n;++i)
{
for(int j=x;j<=len[i];++j)
{
LL nowhash=(f[i][j]-(f[i][j-x]*cv)%Mod+Mod)%Mod;
if(vis[nowhash]!=i)
{
++times[nowhash];
vis[nowhash]=i;
if(times[nowhash]==n)
return true;
}
}
}
return false;
} void prehash(int i)
{
f[i][]=str[]-'a'+;
for(int j=;j<=len[i];++j)
f[i][j]=(f[i][j-]*D+(str[j-]-'a'+))%Mod;
} void dichotomy()
{
int l=,r=minl+;
while(l<r)
{
int mid=(l+r)>>;
if(check(mid))
ans=mid,l=mid+;
else
r=mid;
}
printf("%d",ans);
} int main()
{
freopen("pow.in", "r", stdin);
freopen("pow.out", "w", stdout);
scanf("%d",&n);
minl=INF;
for(int i=;i<=n;++i)
{
scanf("%s",str);
len[i]=strlen(str);
if(len[i]<minl) minl=len[i];
prehash(i);
}
g[]=;
for(int i=;i<=minl;++i)
g[i]=1LL*g[i-]*D%Mod;
dichotomy();
return ;
}
【テンプレート】字符串hash的更多相关文章
- [知识点]字符串Hash
1.前言 字符串的几大主要算法都多少提及过,现在来讲讲一个称不上什么算法, 但是非常常用的东西——字符串Hash. 2.Hash的概念 Hash更详细的概念不多说了,它的作用在于能够对复杂的状态进行简 ...
- 【BZOJ-3555】企鹅QQ 字符串Hash
3555: [Ctsc2014]企鹅QQ Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1545 Solved: 593[Submit][Statu ...
- POJ 1200 字符串HASH
题目链接:http://poj.org/problem?id=1200 题意:给定一个字符串,字符串只有NC个不同的字符,问这个字符串所有长度为N的子串有多少个不相同. 思路:字符串HASH,因为只有 ...
- LA4671 K-neighbor substrings(FFT + 字符串Hash)
题目 Source http://acm.hust.edu.cn/vjudge/problem/19225 Description The Hamming distance between two s ...
- 各种字符串Hash函数比较(转)
常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法.这些函数使用位运算使得每一个字符都对最后的函数值产生影响.另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎 ...
- 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774
Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在 ...
- 字符串hash - POJ 3461 Oulipo
Oulipo Problem's Link ---------------------------------------------------------------------------- M ...
- 长度有限制的字符串hash函数
长度有限制的字符串hash函数 DJBHash是一种非常流行的算法,俗称"Times33"算法.Times33的算法很简单,就是不断的乘33,原型如下 hash(i) = hash ...
- hdu 4622 Reincarnation 字符串hash 模板题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给定一个长度不超过2000的字符串,之后有不超过1e5次的区间查询,输出每次查询区间中不同 ...
- [转]各种字符串Hash函数比较
转自:https://www.byvoid.com/zht/blog/string-hash-compare 常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法.这些 ...
随机推荐
- golang 单元测试(一)
单元测试函数类型 Test(功能测试) 函数规则: 函数名: TestXxxx , 以Test为前缀.Xxxx以大写字母开头 参数类型: *testing.T func TestXxxx(t *tes ...
- 在微服务架构中service mesh是什么?
在微服务架构中service mesh是什么 什么是 service mesh ? 微服务架构将软件功能隔离为多个独立的服务,这些服务可独立部署,高度可维护和可测试,并围绕特定业务功能进行组织. 这些 ...
- rabbitMQ 重试
rabbitMQ 重试机制 spring.rabbitmq.listener.simple.retry.max-attempts=5 最大重试次数spring.rabbitmq.listener.si ...
- 使用winsw将springboot打包的jar注册系统本地服务
1.下载winsw 下载地址:https://github.com/kohsuke/winsw/releases 我这里下载的是2.3.0版. 下载sample-minimal.xml和WinSW.N ...
- Git pull记住密码
在使用https git拉取代码时,每次git pull的时候都会让输入用户名和密码 进入项目目录 命令:git config --global credential.helper store 然后会 ...
- 解决Maven 编译出的jar中没有主清单属性
出现这个问题的原因是 pom 中没有添加主程序入口 在配置中添加如下配置 <plugin> <groupId>org.apache.maven.plugins</grou ...
- iOS - FMDB数据库的使用
下面不废话了直接上代码
- 模板、中间件以及MVC与MTV
模板 基本数据类型的渲染 {#基础数据类型的渲染#} {#1. 变量#} {{ name }} {#2. 列表#} {#通过点索引可以取值#} {{ list.0 }} {#for循环取值#} {% ...
- java保证多线程的执行顺序
1. java多线程环境中,如何保证多个线程按指定的顺序执行呢? 1.1 通过thread的join方法保证多线程的顺序执行, wait是让主线程等待 比如一个main方法里面先后运行thread1, ...
- Hive调优笔记
Hive调优 先记录了这么多,日后如果有遇到,再补充. fetch模式 <property> <name>hive.fetch.task.conversion</name ...