unordered_map 的哈希函数

题目链接:http://codeforces.com/contest/1133/problem/D
上篇博客的题:https://mp.csdn.net/mdeditor/88364092#

用了map<pair<int, int>, int > p; AC的。

现在我想知道用unordered_map是否会快一些。
把map换成unordered_map编译报错。不允许这样定义。应该是没有pair<int, int>, int >的哈希函数。

没有办法只有自己把pair<int, int>哈希处理成long long

unordered_map<LL LL, int> p;

//哈希函数
//如果保证Hash比a, b都大。
//那么不同pair<int, int>映射成的long long一定不同。
//保证没有冲突
LL HX(LL a, LL b)
{
    return a*Hash+b;
}

p[HX(a[i], b[i])]++;

提交:
T
显然:这题卡unordered_map

不要慌cf上有篇博客教你怎样卡unordered_map和防止unordered_map被卡。附上博客地址:http://codeforces.com/blog/entry/62393。

把代码改了一下。
在这里插入图片描述

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

全部代码:

#include<bits/stdc++.h>
#define LL long long
#define p1 first
#define p2 second
using namespace std;
const LL mod=1e9+1;
//memset(a, 0, sizeof(a));
//stack堆栈 queue队列 priority_queue优先队列
//vector向量 multiset平衡二叉树 deque双端队列
//pair{T1 first;T2 second;} greater<T>
//unordered_map 哈希map

int a[200005];
int b[200005];

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

unordered_map<long long, int, custom_hash> p;
//gp_hash_table<long long, int, custom_hash> safe_hash_table;

LL HX(LL a, LL b)
{
    return a*mod+b;
}

int main()
{
    int n, u=0;
    scanf("%d",&n);
    for(int i=0; i<n; i++)
    {
        scanf("%lld",&a[i]);
    }
    for(int i=0; i<n; i++)
    {
        scanf("%lld",&b[i]);
    }
    for(int i=0; i<n; i++)
    {
        if(a[i]==0&&b[i]==0)
        {
            u++;
        }
        else if(a[i]==0)
        {

        }
        else
        {
            LL g=__gcd(a[i], b[i]);
            a[i]/=g, b[i]/=g;
            p[HX(a[i], b[i])]++;
        }
    }
    int MAX=0;
    for(unordered_map<long long, int, custom_hash>::iterator i=p.begin();i!=p.end();i++)
    {
        MAX=max(int(i->p2), MAX);
    }
    cout<<MAX+u<<endl;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值