zoukankan      html  css  js  c++  java
  • [hash] 哈希的简单入门

    算法竞赛中的哈希是往往是种种概率/玄学但是又贼鸡儿快方便的神奇算法

    本质是通过对目标数据建立唯一映射进行缩小数据规模的权值判断, 常常可以乱搞一些题目


    对循环数组的hash

    https://www.acwing.com/problem/content/139/

     解题思路: 对每个六元组求最小表示, 然后用乘积与和对应的双hash映射入一个链表 再判断即可


    字符串哈希

     https://www.acwing.com/problem/content/140/       子串hash模板题

    http://www.51nod.com/Challenge/Problem.html#!#problemId=1089   最长回文子串hash O(n) 算法 

    再也不用记马拉车了233

    解法: 字符串hash常使用进制转化法, 具有类前缀和的性质

    MODhash

    const ull MOD = 386910137;
    ull pre[MAXN];
    ull fac[MAXN] = {1}; 
    
    ull gethash(ull *pre, int a, int b)
    {
    	return (pre[b] - pre[a - 1] * fac[b - a + 1] % MOD + MOD) % MOD;	
    }
    
    fr(i, 1, 1e6 + 10) //预处理阶乘
    {
    	fac[i] = (fac[i - 1] * P) % MOD;
    }
    
    pre[flag] = (pre[flag - 1] * P % MOD + x[j]) % MOD; //预处理hash

    自然溢出 

    ull pre[MAXN], fac[MAXN] = {1}; //自然溢出法 
    
    cin >> s + 1
    
    for(int i = 1; i <= len; ++i) //建立hash table
    {
    	fac[i] = fac[i - 1] * P;
    	pre[i] = pre[i - 1] * P + s[i];
    }
        	
    ull getprehash(int a, int b) //查询任意字串的hash值
    {
    	return pre[b] - pre[a - 1] * fac[b - a + 1];	
    }

    最长回文子串的hash求法

    /*
        Zeolim - An AC a day keeps the bug away
    */
    
    //pragma GCC optimize(2)
    #include <cstdio>
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include <cctype>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <set>
    #include <sstream>
    #include <map>
    #include <ctime>
    #include <vector>
    #include <fstream>
    #include <list>
    #include <iomanip>
    #include <numeric>
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const ld PI = acos(-1.0);
    const ld E = exp(1.0);
    const int INF = 0x3f3f3f3f;
    const int MAXN = 1e6 + 10;
    const ll MOD = 1e9 + 7;
    const ull P = 131;
    
    ull pre[MAXN], fac[MAXN] = {1}, pio[MAXN];
    
    char s[MAXN];
    
    ull getprehash(int a, int b)
    {
    	return pre[b] - pre[a - 1] * fac[b - a + 1];	
    }
    ull getpiohash(int a, int b)
    {
    	return pio[a] - pio[b + 1] * fac[b - a + 1];
    }
    
    int main()
    {
        //ios::sync_with_stdio(false);
        //cin.tie(0);     cout.tie(0);
        //freopen("D://test.in", "r", stdin);
        //freopen("D://test.out", "w", stdout);
    	
    	int flag = 1;
    	
        while(cin >> s + 1)
        {
        	if(s[1] == 'E' && s[2] == 'N' && s[3] == 'D')
        		break;
    
        	int len = strlen(s + 1);
    
        	pio[len + 1] = 1;
        	
        	int ans = 1, pis = 0, apis = 0;
    
        	for(int i = 1; i <= len; ++i)
        	{
        		fac[i] = fac[i - 1] * P;
        		pre[i] = pre[i - 1] * P + s[i];
        	}
        	
        	for(int i = len; i >= 1; --i)
        	{
        		pio[i] = pio[i + 1] * P + s[i];
    		}
    		
    
        	for(int i = 1; i <= len; ++i)
        	{
        		int rpis = pis + 1;
        		
        		while(i - rpis >= 1 && i + rpis <= len && getprehash(i - rpis, i) == getpiohash(i, i + rpis))
        		{
        			ans = max(ans, rpis * 2 + 1), pis = rpis, ++rpis;
    			}
    			
    			rpis = apis;
    			
    			while(i + 1 - rpis >= 1 && i + rpis <= len && getprehash(i - rpis + 1, i + 1) == getpiohash(i, i + rpis))
    			{
    				ans = max(ans, rpis * 2), apis = rpis, ++rpis;
    			}
        	}
        	
        	cout << ans << '
    ';
        }
    
        return 0;
    }
  • 相关阅读:
    33.数组声明方式(var构造函数) 、检测数组类型、数组的属性(封装好的就一个length)、数组的方法
    31.this指向(写出调用链,找最近对象) this的默认绑定 隐式绑定 显示绑定(call(绑定对象) apply(绑定对象) 当括号内没放绑定对象的时候恢复默认绑定) bind
    31.
    30.函数作用域链 (GO AO 也叫词法作用域链)、 调用栈、调用栈涉及this绑定
    29.包装类(构造函数) 包装类作用及调用栈
    916. Word Subsets
    246. Strobogrammatic Number
    445. Add Two Numbers II
    2. Add Two Numbers
    341. Flatten Nested List Iterator
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270374.html
Copyright © 2011-2022 走看看