手写哈希表
众所周知,STL 内置的 unodered_map 已经废了。
取而代之的是 __gnu_pbds::cc(gp)_hash_table
不过这两个也跑的不如手写的快,参考了 耳朵龙_ 的哈希函数,在 born_to_sun 语法指导下,手写了一个 unordered_map。
目前来看效率和 耳朵龙_ 的差不多,欢迎测速来卡。
不过适用性上加强了,支持了结构体的插入。
template<unsigned Sz,unsigned M,typename T1,typename T2,ULL (*get)(T1)> struct UMap
{
//Sz: the number of times opeator[] is called
//M: number of buckets
//T1: key type(any type you want,note that you should ensure "==" is defined)
//T2: value type(any type you want)
//get(T1): the function that trans "T1" into "ULL"
int h[M],len,ne[Sz+1];
struct Data
{
T1 key;
T2 val;
}e[Sz+1];
unsigned Hash(ULL x)const
{
static const ULL t=
std::chrono::steady_clock::now().time_since_epoch().count();
x+=t+0x9e3779b97f4a7c15;
x=(x^(x>>30))*0xbf58476d1ce4e5b9;
x=(x^(x>>27))*0x94d049bb133111eb;
return(x^(x>>31))%M;
}
inline int find(const T1 &v,int type=0)
{
int u=Hash(get(v));
for(int i=h[u];i;i=ne[i]) if(e[i].key==v) return i;
if(type) ++len,e[len].key=v,ne[len]=h[u],h[u]=len;
return len;
}
inline T2 &operator[](const T1 &v)
{
int i=find(v,1);
return e[i].val;
}
inline bool count(const T1 &v)
{
return find(v)!=0;
}
inline int size()
{
return len;
}
Data *begin(){return e+1;}
Data *end(){return e+len+1;}
};
食用例子
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
typedef unsigned long long ULL;
const int N=2e7+5,Inf=1e9,mod=1e8+7;
mt19937 rnd(time(0));
int n;
inline bool operator==(PII &A,PII &B)
{
return (A.x==B.x && A.y==B.y);
}
bool St;
template<unsigned Sz,unsigned M,typename T1,typename T2,ULL (*get)(T1)> struct UMap
{
//Sz: the number of times opeator[] is called
//M: number of buckets
//T1: key type(any type you want,note that you should ensure "==" is defined)
//T2: value type(any type you want)
//get(T1): the function that trans "T1" into "ULL"
int h[M],len,ne[Sz+1];
struct Data
{
T1 key;
T2 val;
}e[Sz+1];
unsigned Hash(ULL x)const
{
static const ULL t=
std::chrono::steady_clock::now().time_since_epoch().count();
x+=t+0x9e3779b97f4a7c15;
x=(x^(x>>30))*0xbf58476d1ce4e5b9;
x=(x^(x>>27))*0x94d049bb133111eb;
return(x^(x>>31))%M;
}
inline int find(const T1 &v,int type=0)
{
int u=Hash(get(v));
for(int i=h[u];i;i=ne[i]) if(e[i].key==v) return i;
if(type) ++len,e[len].key=v,ne[len]=h[u],h[u]=len;
return len;
}
inline T2 &operator[](const T1 &v)
{
int i=find(v,1);
return e[i].val;
}
inline bool count(const T1 &v)
{
return find(v)!=0;
}
inline int size()
{
return len;
}
Data *begin(){return e+1;}
Data *end(){return e+len+1;}
};
inline ULL Hash(PII it)
{
return (ULL)(it.x+Inf)*Inf+(it.y+Inf);
}
UMap<N,mod,PII,int,Hash> Map;
bool Ed;
int Rand(int l,int r)
{
return rnd()%(r-l+1)+l;
}
signed main()
{
cerr<<(&St-&Ed)/1024.0/1024<<"\n";
double st=clock();
n=20000000;
for(int i=1;i<=n;i++)
{
int x=Rand(-Inf,Inf),y=Rand(-Inf,Inf),z=i;
Map[{x,y}]=z;
}
LL res=0;
for(auto [it,w]:Map) res+=w;
cout<<Map.size()<<" "<<res<<"\n";
double ed=clock();
cerr<<(ed-st)/CLOCKS_PER_SEC<<"\n";
return 0;
}

浙公网安备 33010602011771号