H Hash Function
题意
给定一个集合,求一个数 mod 使得 集合中任意两个数 a i % m o d ! = a j % m o d a_i \% mod != a_j \% mod ai%mod!=aj%mod
上述问题可以转化为 任意的两个数的差对 mod 取余不等于 0
可知任意两个数差值的因子都不能满足条件,即找出最小的非** ∀ i , j ∈ [ 1 , n ] , ∣ a i − a j ∣ \forall i,j\in [1,n],\ |a_i-a_j| ∀i,j∈[1,n], ∣ai−aj∣**的因子
朴素求任意两个数的差时间复杂度为 O ( n 2 ) O(n^2) O(n2)
于是可以考虑用 FFT 加速
将多项式中第 a i a_i ai 项系数取值为 1,其余系数为 0 该多项式即为 A A A
对应多项式 B B B 为 第 − a i -a_i −ai 为 1,其余系数为 0,则考虑通过加上一个常数抵消负数
于是 A ∗ B A*B A∗B 的结果中,有系数的项 p i p_i pi即表示:集合中任意两个数的差值 p i p_i pi存在
之后从 n n n开始枚举因子即可
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define rep(i, j, k) for (ll(i) = (j); (i) <= (k); (++i))
typedef long long ll;
typedef complex<double> cp;
const int lim = 1 << 21;
const double pi = acos(-1);
cp a[lim], b[lim]; // 多项式 A B
int rev[lim];
void fft(cp *a, int n, int inv) {
int bit = 0;
while ((1 << bit) < n)
bit++;
rep(i, 0, n - 1) {
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
if (i < rev[i])
swap(a[i], a[rev[i]]);
}
for (int mid = 1; mid < n; mid *= 2) {
cp temp(cos(pi / mid), inv * sin(pi / mid));
for (int i = 0; i < n; i += mid * 2) {
cp omega(1, 0);
for (int j = 0; j < mid; ++j, omega *= temp) {
cp x = a[i + j], y = omega * a[i + j + mid];
a[i + j] = x + y, a[i + j + mid] = x - y;
}
}
}
if (inv == -1)
for (int i = 0; i < lim; ++i)
a[i].real(a[i].real() / n);
}
bool vis[lim];
const int P = 500001;
bool check(int x) {
for (int i = x; i <= P; i += x)
if (vis[i] == 1)
return 0;
return 1;
}
signed main() {
int t, n, m;
cin >> n;
rep(i, 0, n - 1) {
cin >> t;
a[t] = {1, 0};
b[P - t] = {1, 0};
}
int num = 1 << 20;
fft(a, num, 1);
fft(b, num, 1);
rep(i, 0, num - 1) a[i] *= b[i];
fft(a, num, -1);
rep(i, 0, num) {
t = floor(a[i].real() + 0.5);
if (t > 0)
vis[abs(i - P)] = 1;
}
rep(i, n, P) if (check(i)) {
printf("%d\n", i);
break;
}
return 0;
}