多校1 Hash Function
ai % seed != aj %seed,那么|ai-aj|%seed != 0,|ai-aj|的集合中元素可以用fft组合出来,既然|ai-aj|不能整除seed,同时也说明seed不是任何一个|ai-aj|的因子,因此我们还要筛出每个数的因子,筛因子可以做到O(nlogn)
#include <bits/stdc++.h> using namespace std; const int N = 2000010, base = 500001; const double PI = acos(-1); struct Complex { double x, y; Complex operator+ (const Complex& t) { return {x + t.x, y + t.y}; } Complex operator- (const Complex& t) { return {x - t.x, y - t.y}; } Complex operator* (const Complex &t) { return {x * t.x - y * t.y, x * t.y + y * t.x}; } }a[N], b[N]; bool st[N]; int rev[N], tot, bit; void fft(Complex a[], int inv) { for (int i = 0; i < tot; i ++ ) if (i < rev[i]) swap(a[i], a[rev[i]]); for (int mid = 1; mid < tot; mid <<= 1) { auto w1 = Complex({cos(PI / mid), inv * sin(PI / mid)}); for (int i = 0; i < tot; i += mid * 2) { auto wk = Complex({1, 0}); for (int j = 0; j < mid; j ++, wk = wk * w1) { auto x = a[i + j], y = wk * a[i + j + mid]; a[i + j] = x + y, a[i + j + mid] = x - y; } } } } bool check(int x) { for (int i = x; i <= base; i += x) if (st[i]) return false; return true; } int main() { int n; scanf("%d", &n); for (int i = 1; i <= n; i ++ ) { int w; scanf("%d", &w); a[w].x = 1; b[base - w].x = 1; //负数做偏移 } while ((1 << bit) < base * 2) bit ++ ; tot = 1 << bit; for (int i = 0; i < tot; i ++ ) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1)); fft(a, 1), fft(b, 1); for (int i = 0; i < tot; i ++ ) a[i] = a[i] * b[i]; fft(a, -1); for (int i = 0; i < tot; i ++ ) { int w = a[i].x / tot + 0.5; if (w) st[abs(i - base)] = true; } for (int i = n; i <= base; i ++ ) if (check(i)) { printf("%d\n", i); break; } return 0; }