题解 | #Hash Function#

Hash Function

https://ac.nowcoder.com/acm/contest/11166/H

个数两个相减(相加)先序知识

Describe

给定 个数 :
的集合

注意: 指的是 中的每一个元素与 中的每一个元素相加,即

相关题型:Hash Function B-小圆前辈的素数

Solve

朴素双重循环复杂度为 ,对于数据量大于 的问题显然无法解决。

考虑 我们将上述集合换一种表达式:
则对于 ,转化为

因此,我们只要将一个多项式中的 的系数赋值为 ,其他赋值为 。进行一遍FFT后,检验 的系数,若 的系数大于等于 ,则

提示:对于减法,实际上是加上一个负数,因为负下标的问题,可以先统一加上一个偏移量,最后减去即可得到原值。

具体问题讲解
题面描述 [Hash Function]

给定一个集合
考虑 ,求最小的整数 ,使得 无冲突,即若 ,则

Slove

我们需要考虑的是 ,都存在 .

上述结论很容易证明:

考虑: ,则
显然
如果 ,则 。则 不合法。

也就是说 的因子全都不满足条件,同时对于其他数,一定都是满足条件的,证明如下:

因为 ;且 ;则
说明 ,同时对于每一对 都成立,故该 合法。

综上所述:我们需要快速求出所有的 ,并求出 的所有因子。

即我们需要求出
上述做法即可在 内完成,根据经验,中元素不超过个,同时元素不超过 ,用正向筛选法可以在内筛选出所有因子。

代码:

#include <cstdio>
#include <complex>
#include <cmath>
using namespace std;

int n,m;
typedef complex<double> CP;
const int lim = 1<<21;
const double Pi = acos(-1);
const int P = 500001;
CP a[lim],b[lim];
bool vis[lim];

void FFT(CP *x,int lim,int inv) // 板子而已
{
   int bit = 1,m;
   CP stand,now,temp;
   while((1<<bit) < lim) ++bit;
   for (int i = 0; i < lim; ++i)
   {
       m = 0;
       for (int j = 0; j < bit; ++j)
           if(i & (1<<j)) m |= (1<<(bit-j-1));
       if(i < m) swap(x[m],x[i]);
   }
   for (int len = 2; len <= lim; len <<= 1)
   {
       m = len >> 1;
       stand = CP(cos(2*Pi/len),inv*sin(2*Pi/len));
       for (CP *p = x; p != x+lim; p += len)
       {
           now = CP(1,0);
           for (int i = 0; i < m; ++i,now*=stand)
           {
               temp = now * p[i+m];
               p[i+m] = p[i] - temp;
               p[i] = p[i] + temp;
           }
       }
   }
   if(inv == -1) 
       for (int i = 0; i < lim; ++i)
           x[i].real(x[i].real()/lim);
}

bool check(int x)
{
   for (int i = x; i <= P; i += x)
   {
       if (vis[i] == 1) return 0;
   }
   return 1;
}

int main()
{
   int x;
   scanf("%d",&n);
   for (int i = 0; i < n; ++i)
   {
       scanf("%d",&x);
       a[x].real(1);
       b[P - x].real(1); // 负数做偏移
   }
   int num = 1 << 20;
   FFT(a,num,1);
   FFT(b,num,1);
   for (int i = 0; i < num; ++i)
       a[i] *= b[i];
   FFT(a,num,-1);
   for (int i = 0; i <= num; ++i)
   {
       x = (int)floor(a[i].real()+0.5);
       if (x > 0) vis[abs(i - P)] = 1;
   }
   for (int  i = n; i < P+1; ++i)
       if (check(i))
       {
           printf ("%d\n",i);
           break;
       }
   return 0;
}
全部评论

相关推荐

27届学院本誓死冲击...:自我评价和校园经历全删了,荣誉经历只留奖学金,项目也全得换都不如外卖
点赞 评论 收藏
分享
评论
45
收藏
分享

创作者周榜

更多
正在热议
更多
# 春招至今,你的战绩如何? #
8136次浏览 75人参与
# 你的实习产出是真实的还是包装的? #
1493次浏览 37人参与
# MiniMax求职进展汇总 #
23523次浏览 305人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7266次浏览 40人参与
# 简历第一个项目做什么 #
31433次浏览 319人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
186697次浏览 1118人参与
# 巨人网络春招 #
11265次浏览 223人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152171次浏览 887人参与
# 研究所笔面经互助 #
118827次浏览 577人参与
# 重来一次,我还会选择这个专业吗 #
433206次浏览 3924人参与
# 简历中的项目经历要怎么写? #
309816次浏览 4176人参与
# 面试紧张时你会有什么表现? #
30452次浏览 188人参与
# 你今年的平均薪资是多少? #
212883次浏览 1039人参与
# AI时代,哪些岗位最容易被淘汰 #
63109次浏览 773人参与
# 我的求职精神状态 #
447904次浏览 3128人参与
# 你最满意的offer薪资是哪家公司? #
76323次浏览 374人参与
# 正在春招的你,也参与了去年秋招吗? #
362991次浏览 2635人参与
# 你怎么看待AI面试 #
179654次浏览 1206人参与
# 牛客AI文生图 #
21374次浏览 237人参与
# 职能管理面试记录 #
10766次浏览 59人参与
# 网易游戏笔试 #
6420次浏览 83人参与
# 腾讯音乐求职进展汇总 #
160518次浏览 1108人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务