内容参考《算法竞赛进阶指南》

之前集训的时候听老师讲过,字符串题目中,hash一般不是正解,但是是一个优秀的暴力,可以拿比较多的部分分。

hash涉及内容很多,这里只讨论字符串hash

可以把字符串看成一个131进制位数,然后用ull储存,大过2的64次方后自动取模。

这样的话hash值相等的话可以认为两个字符串是一样的(极少概率不一样)

所以对于一个字符串,我们可以用O(n)的时间内算出所有前缀的hash值,然后就可以用

O(1)的时间算出任意一段区间的hash值(类比二进制操作,具体看代码)。

Hash大法吼啊!!!

怎么用呢?

问题:给你一个字符串,每次询问两个区间[l1, r1][l2, r2],判断两个区间的字符是否相等

#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std; typedef unsigned long long ull;
const int MAXN = 1e6 + 10;
const int base = 131;
char s[MAXN];
int n, q;
ull p[MAXN], f[MAXN]; inline ull cut(int l, int r)
{
return f[r] - f[l - 1] * p[r - l + 1];
} int main()
{
scanf("%d%d", &n, &q); //n为字符串长度
scanf("%s", s + 1);
p[0] = 1;
_for(i, 1, n)
{
f[i] = f[i - 1] * base + (s[i] - 'a' + 1);
p[i] = p[i - 1] * base;
}
while(q--)
{
int l1, r1, l2, r2;
scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
if(cut(l1, r1) == cut(l2, r2)) puts("Yes");
else puts("No");
}
return 0;
}

用Hash大法解决kmp问题

比较hash值就好了,非常简单粗暴!!!(但效率比KMP慢一些,所以说是一个优秀的暴力)

caioj 1177 KMP模版

#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std; typedef unsigned long long ull;
const int MAXN = 1e6 + 10;
const int base = 131;
char a[MAXN], b[MAXN];
int n, q, lena, lenb;
ull p[MAXN], f[MAXN], t; inline ull cut(int l, int r)
{
return f[r] - f[l - 1] * p[r - l + 1];
} int main()
{
scanf("%s%s", a + 1, b + 1);
lena = strlen(a + 1); lenb = strlen(b + 1);
p[0] = 1;
_for(i, 1, lena)
{
f[i] = f[i - 1] * base + (a[i] - 'a' + 1);
p[i] = p[i - 1] * base;
}
_for(i, 1, lenb) t = t * base + (b[i] - 'a' + 1);
_for(i, 1, lena)
{
if(cut(i, i + lenb - 1) == t)
{
printf("%d %d\n", i, i + lenb - 1);
break;
}
if(i == lena) puts("NO");
}
return 0;
}

Hash大法的更多相关文章

  1. hdu5183 hash大法

    维护前缀和sum[i]=a[0]-a[1]+a[2]-a[3]+…+(-1)^i*a[i]枚举结尾i,然后在hash表中查询是否存在sum[i]-K的值.如果当前i为奇数,则将sum[i]插入到has ...

  2. NOIP 2014 D2T3 解方程 Hash大法好

    题目大意:给定高次方程an*x^n+...+a1*x^1+a0*x^0=0 求[1,m]区间内有多少个整数根 ai<=10^10000.m<=100W 懒得高精,考场上写的long dou ...

  3. LeetCodeTwo Sum IV 树的遍历+Hash大法好

    题意 给定一颗二叉搜索树,返回是否存在两个节点的值之和为给定值K. 思路 同Two Sum.使用Hash表解决.只是要写个树的遍历而已,选取DFS. 源码 class Solution { publi ...

  4. POJ 1743 Musical Theme Hash+二分法

    标题效果:有一个美丽的旋律,它们是由一些不大于88音调.如果计为五个音调的量度,问:是否有相同的节奏的多个部分(相同的差,以及两者之间的相同的节奏不能重叠),并寻求最长长度. 思考:这个问题是八人中的 ...

  5. 【线段树 集合hash】bzoj4373: 算术天才⑨与等差数列

    hash大法好(@ARZhu):大数相乘及时取模真的是件麻烦事情 Description 算术天才⑨非常喜欢和等差数列玩耍.有一天,他给了你一个长度为n的序列,其中第i个数为a[i].他想考考你,每次 ...

  6. LeetCode longest substring without repeating characters 题解 Hash表

    题目 Given a string, find the length of the longest substring without repeating characters. Example 1: ...

  7. 【Tyvj 1060】【NOIP 2005】等价表达式

    设a为一个质数,模数为另一个质数,然后暴力算多项式的答案,如果答案相等就认为两个多项式相等. 这种hash有出错概率的题为什么还是要用hash呢?因为出错的概率实在太小了,a和模数的值取得好出题人根本 ...

  8. bzoj4264: 小C找朋友

    hash大法好 #include <iostream> #include <cstdio> #include <cstring> #include <cmat ...

  9. bzoj4337: BJOI2015 树的同构

    hash大法好 #include <iostream> #include <cstdio> #include <cstring> #include <cmat ...

随机推荐

  1. 基于mybatis的CRUD

    u  基于Mybatis的CRUD u  掌握MyBatis的结果类型-resultMap和resultType u  掌握MyBatis的参数类型 u  掌握#和$两种语法 1      基于myb ...

  2. 《编程导论(Java)&#183;7.4.4 String对象问题》

    String是Java API中使用频率第一的类,曾经在CSDN论坛上.至少每一个月都有相关的贴子,讨论==和equals(). 本节介绍这一部分的内容,也有一个重要更正. String文字在程序中被 ...

  3. Eclipse开发C/C++程序的MinGw配置

    环境变量设置: a.鼠标右击桌面"计算机"(WindowsXp是"我的电脑")->"属性" b.WindowsXP时,在新弹出的属性窗 ...

  4. Create a Visual C++ Wizard for Visual Studio 2005

    from:http://www.codeguru.com/cpp/v-s/devstudio_macros/customappwizards/article.php/c12775/Create-a-V ...

  5. android WebViewClient和WebChromeClient

    一.Android之WebViewClient与WebChromeClient的区别 ANDROID应用开发的时候可能会用到WEBVIEW这个组件,使用过程中可能会接触到WEBVIEWCLIENT与W ...

  6. hmm CDN检测

    # -*- coding:utf-8 -*- import sys import re from hmmlearn import hmm import numpy as np from sklearn ...

  7. hdoj--5240--Exam()

    Exam Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  8. 2017第33周四JDK8并发

    Java 8在Lambda表达式.接口默认方式.新的日期API等方面引入的新特性广受关注,同时在并发编程方面也做出了大量改进.以往的几个Java版本都对java.util.concurrent做了不同 ...

  9. vue --- 关于多个router-view视图组件,渲染同一页面

    vue.js多视图的使用,可以提高网页组件化,模块化 比如使用多视图,可以将网站页面封装header.footer.navbar等多个公共部分, 遇到修改公共部分的文案信息等数据的时候,不再需要逐一修 ...

  10. ROS-SLAM仿真-cartographer

    前言:cartographer是谷歌2016年发布的一个开源slam算法,采用基于图网络的优化方法,主要基于激光雷达来实现. 使用源码编译方式. 一.新建工作空间 1.1 使用roboware新建名为 ...