Hash Perfectly

题目连接:

http://acm.uestc.edu.cn/#/problem/show/1314

Description

In computing, a hash table is a data structure used to implement an associative array, a structure that can map keys to values.

A hash table uses a hash function to compute an index into an array of buckets or slots, from which the desired value can be found. A common hash function is \(index=key\ \%\ array\\_size\) (\(\%\) is modulo operator), but it may cause some collisions.

For example, if keys are \(1,2,6,10\), and we choose \(array\\_size=4\), the indexes will be \(1,2,2,2\), where some collisions happen.

To solve the collision, we can use the method known as separate chaining with linked lists.

Seeing the example again, when we try to insert \(6\), because its index \(2\) is used, we build a linked list in index \(2\), and there would be \(2\rightarrow 6\) in index \(2\). Insert \(10\) next, there would be a linked list \(2\rightarrow 6\rightarrow 10\) in index 2.

To calculate the efficiency of the hash function, we define a value called \(ASL\) (Average search length):

\[ASL=\frac{1}{n}\sum_{i=1}^{n}c_i
\]

\(c_i\) is the number of times to compare when we search the \(i^{th}\) key.

Using the example above again, \(c_1=1,c_2=1,c_3=2,c_4=3\), so \(ASL=\frac{1}{4}(1+1+2+3)=1.75\).

It's obvious that \(ASL\) can minimize when we choose a sufficiently large \(array\\_size\), but in fact due to the limitation of memory, \(array\\_size\) must be no more than \(limit\), i.e., \(1\leq array\\_size\leq limit\).

Now you are given n keys, try to choose a proper \(array\\_size\) to minimize \(ASL\). If there are multiple answers, choose the smallest one.

Input

The first line contains two integers \(n\) and \(limit\).

The second line contains \(n\) integers, where \(i^{th}\) integer indicates the \(i^{th}\) key.

\(1\leq n, limit, key\leq 2*10^5\)

Output

Print the smallest \(array\\_size\) which can minimize \(ASL\).

Sample Input

4 4

1 2 6 10

Sample Output

3

Hint

题意

现在你有n个数,然后哈希是指b[i]=a[i]%k

现在让你找到一个合适的k,使得冲突的对数最少,这个k需满足0<=k<=limit

题解:

若一个位置冲突了k次,则对n*ASL的贡献是k*(k+1)/2,相当于k个数两两冲突的对数加k。

对于两个数a,b,他们只会在(a-b) % array_size == 0时冲突。

利用FFT,可把所有a-b的可能取值对应的个数算出来。对于每个array_size,算出a-b=array_size, a-b=2array_size, a-b=3array_size, …的个数,就可以直接得到ASL的值。

复杂度O(nlogn)

代码

#include<bits/stdc++.h>

using namespace std;

const int N = 600040;
const double pi = acos(-1.0); int len=1<<19; struct Complex
{
double r,i;
Complex(double r=0,double i=0):r(r),i(i) {};
Complex operator+(const Complex &rhs)
{
return Complex(r + rhs.r,i + rhs.i);
}
Complex operator-(const Complex &rhs)
{
return Complex(r - rhs.r,i - rhs.i);
}
Complex operator*(const Complex &rhs)
{
return Complex(r*rhs.r - i*rhs.i,i*rhs.r + r*rhs.i);
}
} va[N],vb[N]; void rader(Complex F[],int len) //len = 2^M,reverse F[i] with F[j] j为i二进制反转
{
int j = len >> 1;
for(int i = 1;i < len - 1;++i)
{
if(i < j) swap(F[i],F[j]); // reverse
int k = len>>1;
while(j>=k)
{
j -= k;
k >>= 1;
}
if(j < k) j += k;
}
} void FFT(Complex F[],int len,int t)
{
rader(F,len);
for(int h=2;h<=len;h<<=1)
{
Complex wn(cos(-t*2*pi/h),sin(-t*2*pi/h));
for(int j=0;j<len;j+=h)
{
Complex E(1,0); //旋转因子
for(int k=j;k<j+h/2;++k)
{
Complex u = F[k];
Complex v = E*F[k+h/2];
F[k] = u+v;
F[k+h/2] = u-v;
E=E*wn;
}
}
}
if(t==-1) //IDFT
for(int i=0;i<len;++i)
F[i].r/=len;
} void Conv(Complex a[],Complex b[],int len) //求卷积
{
FFT(a,len,1);
FFT(b,len,1);
for(int i=0;i<len;++i) a[i] = a[i]*b[i];
FFT(a,len,-1);
}
int n,limit;
int a[N];
long long num[N],sum[N];
void solve()
{
scanf("%d%d",&n,&limit);
int Mx = 0;
for(int i=0;i<n;i++)
{
int x;scanf("%d",&a[i]);
va[a[i]].r+=1;
vb[200000-a[i]].r+=1;
}
Conv(va,vb,len);
for(int i=0;i<=200000;i++)
num[i]=(long long)(va[200000+i].r+0.5);
long long ans1=1e18,ans2=0;
for(int i=1;i<=limit;i++)
{
long long cnt = 0;
for(int j=i;j<=len;j+=i)
cnt+=num[j];
if(cnt<ans1)
{
ans1=cnt;
ans2=i;
}
}
cout<<ans2<<endl;
}
int main()
{
solve();
return 0;
}

CDOJ 1314 Hash Perfectly FFT的更多相关文章

  1. LA4671 K-neighbor substrings(FFT + 字符串Hash)

    题目 Source http://acm.hust.edu.cn/vjudge/problem/19225 Description The Hamming distance between two s ...

  2. 卷积FFT、NTT、FWT

    先简短几句话说说FFT.... 多项式可用系数和点值表示,n个点可确定一个次数小于n的多项式. 多项式乘积为 f(x)*g(x),显然若已知f(x), g(x)的点值,O(n)可求得多项式乘积的点值. ...

  3. FFT初步学习小结

    FFT其实没什么需要特别了解的,了解下原理,(特别推荐算法导论上面的讲解),模板理解就行了.重在运用吧. 处理过程中要特别注意精度. 先上个练习的地址吧: http://vjudge.net/vjud ...

  4. UOJ#335. 【清华集训2017】生成树计数 多项式,FFT,下降幂,分治

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ335.html 前言 CLY大爷随手切这种题. 日常被CLY吊打系列. 题解 首先从 pruffer 编码的角度考虑这个问 ...

  5. 【BZOJ】3160: 万径人踪灭 FFT+回文串

    [题意]给定只含'a'和'b'字符串S,求不全连续的回文子序列数.n<=10^5. [算法]FFT+回文串 [题解]不全连续的回文子序列数=回文子序列总数-回文子串数. 回文子串数可以用回文串算 ...

  6. UVALive - 4671 K-neighbor substrings (FFT+哈希)

    题意:海明距离的定义:两个相同长度的字符串中不同的字符数.现给出母串A和模式串B,求A中有多少与B海明距离<=k的不同子串 分析:将字符a视作1,b视作0.则A与B中都是a的位置乘积是1.现将B ...

  7. [poj] 3690 Constellations || 矩阵hash

    原题 在大矩阵里找有几个小矩阵出现过,多组数据 将t个矩阵hash值放入multiset,再把大矩阵中每个hash值从multiset里扔出去,这样最后剩在multiset里的值就是没有找到的小矩阵, ...

  8. FFT题集

    FFT学习参考这两篇博客,很详细,结合这看,互补. 博客一 博客二 很大一部分题目需要构造多项式相乘来进行计数问题. 1. HDU 1402 A * B Problem Plus 把A和B分别当作多项 ...

  9. BZOJ4259:残缺的字符串(FFT与字符串匹配)

    很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. 你想对这两 ...

随机推荐

  1. Mysql储存过程5: while

    循环结构 while create procedure name() begin while 条件 do SQL语句 end while; end$ create procedure aa6() be ...

  2. Delphi 10 seattle 去掉自带的代码连接线

  3. anychat安装

    1.下载后,解压到一个目录 2.进入anychat核心服务器目录,并启动   ①.cd %anychat安装路径%/binrver     ②../anychatcoreserver -d   3.进 ...

  4. 匿名函数、lambda表达式

    匿名函数 func = lambda x: y #x是形参,y是返回值 键字lambda表示匿名函数,冒号前面的x表示函数参数,冒号后面的y表示匿名函数的返回值. 例1:返回列表中长度大于等于3的元素 ...

  5. charles抓包误点deny处理办法及日常抓包

    误点deny方法在最底下~~ (博文为转载) 我们在开发网站项目的时候,我们可以通过浏览器的debug模式来看request以及response的数据,那么如果我们开发移动端项目没有网页呢?如何抓取数 ...

  6. Linux下如何创建新用户

    Linux下如何创建新用户 Linux系统中,只有root用户有创建其他用户的权限.创建过程如下:   useradd -d /home/newuser newuser(设定了该用户的主目录和用户名) ...

  7. 转- 阿里云、Amazon、Google云数据库方案架构与技术分析

    「一切都会运行在云端」. 云时代早已来临,本文着眼于顶级云服务商云服务商的云数据库方案背后的架构,以及笔者最近观察到的一些对于云数据库有意义的工业界的相关技术的进展,希望读者能有所收获. 现在越来越多 ...

  8. JS函数学习

    =============数学函数========== 1.Math.random()为取随机数0~1之间的:0可以取到,1取不到 alert(Math.random()); 2.Math.PI为3. ...

  9. day5 常用模块json和pickle

    json 和 pickle json和pickle是用于字符串序列化和反序列化的过程,我们在存储和使用的时候,经常把列表存入文件,读取的时候我们还想以列表的形式读取.就需要使用json和pickle. ...

  10. 二安装Python

    因为Python是跨平台的,它可以运行在Windows.Mac和各种Linux/Unix系统上.在Windows上写Python程序,放到Linux上也是能够运行的. 要开始学习Python编程,首先 ...