H - Hash Function
题意: 给出个互不相同的数,找一个最小的模数,使得这些数字对这个模数取模的结果互不相同。
题解:
%
%
转化为
%
- 问题就转化为找一个
,他不是任意一个
的约数
- 问题就来到了如何快速求一个数列中每两个数之间的差,如果暴力是
会超时
- 我们考虑多项式乘法,用指数的减代表两个数直接的差,因为在
中指数不能为负,所以我们将指数整体加
- 做完
后就是枚举
,直到他不是某个
的约数为止,如果找不到则为
- 特判
的情况
#include<bits/stdc++.h> using namespace std; #define dbg(x...) do { cout << #x << " -> "; err(x); } while (0) void err () { cout << endl;} template <class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << ' '; err(args...);} inline int rd() { int f = 0; int x = 0; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) f |= (ch == '-'); for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; if (f) x = -x; return x; } void out(int a) {if(a<0)putchar('-'),a=-a;if(a>=10)out(a/10);putchar(a%10+'0');} #define pt(x) out(x),puts("") #define ll long long #define ull unsigned long long #define LL __int128 #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define pii pair<int, int> #define PII pair<ll, ll> #define fi first #define se second #define pb push_back #define mp(a,b) make_pair(a,b) #define PAUSE system("pause"); const double Pi = acos(-1.0); const double eps = 1e-8; const int maxn = 5e6 + 10; const int maxm = 6e2 + 10; const int mod = 999911659; const int P = 131; inline void swap(ll &a, ll &b){ll t = a; a = b; b = t;} inline ll min(ll a, ll b){return a < b ? a : b;} inline ll max(ll a, ll b){return a > b ? a : b;} // const int mod = 998244353; struct Complex{ double x,y; Complex (double xx=0,double yy=0){x=xx,y=yy;} }a[maxn],b[maxn]; Complex operator + (Complex a,Complex b){ return Complex(a.x+b.x , a.y+b.y);} Complex operator - (Complex a,Complex b){ return Complex(a.x-b.x , a.y-b.y);} Complex operator * (Complex a,Complex b){ return Complex(a.x*b.x-a.y*b.y , a.x*b.y+a.y*b.x);} ll l,r[maxn]; ll limit=1; void fast_fast_tle(Complex *A, int type){ for(int i = 0; i < limit; i++) if(i < r[i]) swap(A[i], A[r[i]]); for(int mid = 1; mid < limit; mid <<= 1){ Complex Wn(cos(Pi/mid), type*sin(Pi / mid)); for(int R = mid << 1, j = 0; j < limit; j += R){ Complex w(1, 0); for(int k = 0; k < mid; k++, w = w * Wn){ Complex x = A[j + k], y = w * A[j + mid + k]; A[j + k] = x + y; A[j + mid + k] = x - y; } } } } ll n, c[maxn]; void solve(){ n = rd(); for(int i = 1; i <= n; i++) { int x = rd(); a[x + 500000] = 1; b[500000 - x] = 1; } if(n == 1) { puts("1"); return ; } while(limit <= 1500000) limit <<= 1, l++; for(int i = 0; i < limit; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1)); fast_fast_tle(a, 1); fast_fast_tle(b, 1); for(int i = 0; i <= limit; i++) a[i] = a[i] * b[i]; fast_fast_tle(a, -1); int minn = inf; for(int i = 1000001, j = 999999; i <= 1500000, j >= 500000; i++, j--) { c[i - 1000000] = (int)(a[i].x/limit+0.5) + (int)(a[j].x/limit + 0.5); } for(int i = 2; i <= 500000; i++) { bool flag = true; for(int j = i; j <= 500000; j += i) { if(c[j]) { flag = false; break; } } if(flag) { printf("%d\n", i); return ; } } puts("500001"); } int main() { // freopen("02.in","r",stdin); int t = 1; // t = rd(); while(t--) solve(); return 0; }