0x14 Hash

Hash表

【例题】POJ3349 Snowflake Snow Snowflakes

建立一个哈希表,将N片雪花依次插入。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 const int INF=0x3f3f3f3f;
 8 const int maxn=100000+10;
 9 const int P=99991;
10 int n;
11
12 int hash(int *a) {
13     int sum=0, mul=1;
14     for (int i=0; i<6; ++i) {
15         sum=(sum+a[i])%P;
16         mul=(long long)mul*a[i]%P;
17     }
18     return (sum+mul)%P;
19 }
20
21 int tot=0, snow[maxn][6], next[maxn], head[maxn];
22 bool judge(int *a, int *b) {
23     for (int i=0; i<6; ++i) {
24         for (int j=0; j<6; ++j) {
25             bool flag=1;
26             //顺时针
27             for (int k=0; k<6; ++k) {
28                 if (a[(i+k)%6] != b[(j+k)%6]) flag=0;
29                 //printf("%d %d %d\n", a[(i+k)%6], b[(j+k)%6], flag);
30             }
31             //printf("\n");
32             if (flag) return 1;
33             //逆时针
34             flag=1;
35             for (int k=0; k<6; ++k) {
36                 if (a[(i+k)%6] != b[(j-k+6)%6]) flag=0;
37                 //printf("%d %d %d\n", a[(i+k)%6], b[(j-k+6)%6], flag);
38             }
39             //printf("\n");
40             if (flag) return 1;
41         }
42     }
43     return 0;
44 }
45
46 bool insert(int *a) {
47     int val=hash(a);
48     for (int i=head[val]; i; i=next[i]) {
49         if (judge(snow[i], a)) return 1;
50     }
51     //若没有找到相同的雪花,则进行插入
52     ++tot;
53     memcpy(snow[tot], a, 6*sizeof(int));
54     next[tot]=head[val];
55     head[val]=tot;
56     return 0;
57 }
58
59 int main() {
60     //freopen("a.out", "w", stdout);
61     scanf("%d", &n);
62     for (int i=1; i<=n; ++i) {
63         int a[10];
64         for (int j=0; j<6; ++j)
65             scanf("%d", &a[j]);
66         if (insert(a)) {
67             printf("Twin snowflakes found.\n");
68             return 0;
69         }
70     }
71     printf("No two snowflakes are alike.\n");
72     return 0;
73 }  

字符串Hash

取一固定值P(一般取131或13331),将字符串看作P进制数,并分配一个大于0的数值,代表每种字符。取一固定值M,求出该P进制数对M的余数,作为该字符的Hash值,通常取M=264,即用unsigned long long类型存储,溢出时自动取模。

【例题】CH1401 兔子与兔子

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 const int INF=0x3f3f3f3f;
 8 const int maxn=1000000+10;
 9 char s[maxn];
10 unsigned long long f[maxn], p[maxn];
11
12 int main() {
13     //freopen("a.txt", "r", stdin);
14     //freopen("a.out", "w", stdout);
15     scanf("%s", s+1);
16     int T;
17     scanf("%d", &T);
18     int n=strlen(s+1);
19     p[0]=1;
20     for (int i=1; i<=n; ++i) {
21         f[i]=f[i-1]*131+(s[i]-‘a‘+1);    //Hash(s[1~i])
22         p[i]=p[i-1]*131;    //131^i
23     }
24     while (T--) {
25         int l1, r1, l2, r2;
26         scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
27         unsigned long long hash1=f[r1]-f[l1-1]*p[r1-l1+1];
28         unsigned long long hash2=f[r2]-f[l2-1]*p[r2-l2+1];
29         if (hash1==hash2) puts("Yes");
30         else puts("No");
31     }
32     return 0;
33 }  

【例题】POJ3974 Palindrome

枚举回文中心,提前预处理出正着和反着的Hash值

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 const int INF=0x3f3f3f3f;
 8 const int maxn=1000000+10;
 9 char s[maxn];
10 unsigned long long f1[maxn], f2[maxn], p[maxn];
11
12 int main() {
13     //freopen("a.txt", "r", stdin);
14     //freopen("a.out", "w", stdout);
15     int kase=0;
16     p[0]=1;
17     for (int i=1; i<=maxn; ++i)
18         p[i]=p[i-1]*131;    //131^i
19     while (~scanf("%s", s+1)) {
20         int n=strlen(s+1);
21         if (n==3&&s[1]==‘E‘&&s[2]==‘N‘&&s[3]==‘D‘)
22             break;
23         printf("Case %d: ", ++kase);
24         for (int i=1; i<=n; ++i)    //正着算一遍
25             f1[i]=f1[i-1]*131+(s[i]-‘a‘+1);
26         for (int i=n; i>=1; --i)    //反着算一遍
27             f2[i]=f2[i+1]*131+(s[i]-‘a‘+1);
28         int ans=-INF;
29         for (int i=1; i<=n; ++i) {    //枚举回文中心
30             int l=1, r=min(i-1, n-i);
31             while (l<r) {    //奇回文串
32                 int mid=(l+r+1)>>1;
33                 if (f1[i-1]-f1[i-1-mid]*p[mid]==f2[i+1]-f2[i+1+mid]*p[mid]) l=mid;
34                 else r=mid-1;
35             }
36             ans=max(ans, l*2+1);
37             l=1, r=min(i, n-i);
38             while (l<r) {    //偶回文串
39                 int mid=(l+r+1)>>1;
40                 if (f1[i]-f1[i-mid]*p[mid]==f2[i+1]-f2[i+1+mid]*p[mid]) l=mid;
41                 else r=mid-1;
42             }
43             ans=max(ans, l*2);
44         }
45         printf("%d\n", ans);
46     }
47     return 0;
48 }  

原文地址:https://www.cnblogs.com/kkkstra/p/11118414.html

时间: 2024-10-18 23:51:11

0x14 Hash的相关文章

通过PowerShell获取Windows系统密码Hash

当你拿到了系统控制权之后如何才能更长的时间内控制已经拿到这台机器呢?作为白帽子,已经在对手防线上撕开一个口子,如果你需要进一步扩大战果,你首先需要做的就是潜伏下来,收集更多的信息便于你判断,便于有更大的收获.用什么方法才能有尽可能高的权限,同时能更有效的隐藏自己,是留webshell,留后门,种木马还是Rootkit?webshell,哪怕是一句话木马都很容易被管理员清除,放了木马,也容易被有经验的管理员查出,不管是早期自己创建进程,进程被干掉就完了,还是注入进程的木马,或者是以服务自启动的木马

一致性hash算法 - consistent hashing

1.背景 我们都知道memcached服务器是不提供分布式功能的,memcached的分布式完全是由客户端来实现的.在部署memcached服务器集群时,我们需要把缓存请求尽可能分散到不同的缓存服务器中,这样可以使得所有的缓存空间都得到利用,而且可以降低单独一台缓存服务器的压力.     最简单的一种实现是,缓存请求时通过计算key的哈希值,取模后映射到不同的memcahed服务器.这种简单的实现在不考虑集群机器动态变化的情况下也是比较有效的一种方案,但是,在分布式集群系统中,简单取模的哈希算法

BZOJ3198 SDOI2013 spring HASH+容斥原理

题意:给定6个长度为n的数列,求有多少个数对(i,j)((i,j)≡(j,i))使得i和j位置恰好有K个数相同,其中0≤K≤6 题解: 设fi=至少有K个数相同的位置对的数量,用2^6枚举每一种可能,根据容斥原理,答案就是\[\sum\limits_{i = K}^N {{f_i}C_i^K{{\left( { - 1} \right)}^{i - K}}} \] 至于多乘一个组合数,是因为当前枚举到有x个数相同,一个位置对有i个相同的数,那么累计的时候就会算成$C_x^i$,因此实际上这个位置

hash算法搜索获得api函数地址的实现

我们一般要获得一个函数的地址,通常采用的是明文,例如定义一个api函数字符串"MessageBoxA",然后在GetProcAddress函数中一个字节一个字节进行比较.这样弊端很多,例如如果我们定义一个杀毒软件比较敏感的api函数字符串,那么可能就会增加杀毒软件对我们的程序的判定值,而且定义这些字符串还有一个弊端是占用的字节数较大.我们想想如何我们的api函数字符串通过算法将它定义成一个4字节的值,然后在GetProcAddress中把AddressOfNames表中的每个地址指向的

BZOJ_3207_花神的嘲讽计划1_(Hash+主席树)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3207 给出一个长度为\(n\)的串,以及\(m\)个长度为\(k\)的串,求每个长度为\(k\)的串在原串\([x,y]\)区间是否出现过. 分析 这道题要求对比长度为\(k\)的串,于是我们把这些串的Hash值都算出来,问题就转化成了求\([x,y]\)的区间中是否出现过某Hash值. 求区间中某一个值出现了多少次,可以用主席树. p.s. 1.学习了主席树指针的写法,比数组慢好多啊...

Hash算法专题

1.[HDU 3068]最长回文 题意:求一个字符串(len<=110000)的最长回文串 解题思路:一般解法是manacher,但是这一题用hash也是可以ac的 假设当前判断的是以i为中心偶数最长回文串,那么s[2*i+1-k……i]与s[i+1……k]的哈希值必定相同 假设当前判断的是以i为中心奇数最长回文串,那么s[2*i-k……i-1]与s[i+1……k]的哈希值必定相同 用二分求出相应的k 1 #include <iostream> 2 #include <algori

Salted hash password

参考文档 http://www.cnblogs.com/richardlee/articles/2511321.html https://en.wikipedia.org/wiki/Salt_%28cryptography%29 https://www.91ri.org/7593.html 密码存储为什么不能是明文? 当账户密码是明文存储的话, 万一本网站给黑客攻破获取了数据, 则用户的账户被泄露.(术语叫 拖库) 当黑客知道了你的账户后, 其可以使用此账户,到其他网站尝试访问, 例如有厉害关系

Golang Hash MD4

//Go标准包中只有MD5的实现 //还好,github上有MD4实现. package main import (     "golang.org/x/crypto/md4"     "encoding/hex"     "fmt" ) func get_md4(buf []byte) ([] byte) { ctx := md4.New() ctx.Write(buf) return ctx.Sum(nil) } func main() {

poj 3320 Jessica&#39;s Reading Problem(尺取法+map/hash)

题目:http://poj.org/problem?id=3320 题意:给定N个元素的数组,找出最短的一段区间使得区间里面的元素种类等于整个数组的元素种类. 分析:暴力枚举区间的起点x,然后找到最小的y,使得区间[x,y]满足条件,x向有移位后变成x',现在的y'肯定不至于在y的左边.存状态的话map和hash都可以. map代码: #include <iostream> #include <set> #include <map> #include <cstdi