Hash Function —— 1H

时间:2021-08-12
本文章向大家介绍Hash Function —— 1H,主要包括Hash Function —— 1H使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Hash Function

题目描述

给定一个序列\(a\),找到一个最小的\(seed\)满足\(h(x) = x \; \% \; seed\),且任意两个数模意义下不一样。

范围

\(n \leq 5 \times 10^5,a_i \leq 10^5\)

题解

题目可以转化为找到一个最小的数\(m\),使得其不是任何一个\(|a_i - a_j|\)的约数。

\(h(A)\)表示\(A\)是否存在,那么\(h(A) = h(i) * h(A - i)\),计算卷积即可,判断每一种差值是否存在。

使用\(FFT\)加速上述过程。

代码

#include <bits/stdc++.h>
using namespace std;

const int N = 2e6 + 10;
const double PI = acos(-1.0);

struct Complex {
	double x,y;
	Complex (double _x = 0.0,double _y = 0.0) {
		x = _x,y = _y;
	}
	Complex operator - (const Complex &b) const {
		return Complex (x - b.x,y - b.y);
	}
	Complex operator + (const Complex &b) const {
		return Complex (x + b.x,y + b.y);
	}
	Complex operator * (const Complex &b) const {
		return Complex (x * b.x - y * b.y,x * b.y + y * b.x);
	}
};
int rev[N];
void change (Complex y[],int len) {
	for(int i = 0;i < len; ++i) {
		rev[i] = rev[i >> 1] >> 1;
		if(i & 1) rev[i] |= len >> 1;
	}
	for(int i = 0;i < len; ++i) {
		if(i < rev[i]) swap(y[i],y[rev[i]]);
	}
}


void fft(Complex y[],int len,int op) {
	change(y,len);
	for(int h = 2;h <= len;h <<= 1) {
		Complex wn (cos(2 * PI / h),sin (op * 2 * PI / h));
		for(int j = 0;j < len; j += h) {
			Complex w(1,0);
			for(int k = j;k < j + (h >> 1); ++k) {
				Complex u = y[k];
				Complex t = w * y[k + (h >> 1)];
				y[k] = u + t;
				y[k + (h >> 1)] = u - t;
				w = w * wn;
			}
		}
	}
	if(op == -1) {
		for(int i = 0;i < len; ++i) {
			y[i].x /= len;
		}
	}
}

int n;
int sum[N];
Complex x1[N],x2[N];
int mx = -1;

int main () {
	cin >> n;
	for (int i = 0;i < n; ++i) {
		int x;
		scanf("%d",&x);
		x1[x].x = 1;
		mx = max(mx,x);
	}
    mx = 500001;
	int len = 0;
	while((1 << len) <= mx << 1) len ++;
	len = 1 << len;
	for(int i = 1;i < len; ++i) {
		x2[i].x = (x1[len - i].x > 0);
	}
	x2[0].x = x1[0].x;
	fft(x1,len,1);fft(x2,len,1);
	for(int i = 0;i < len; ++i) {
		x1[i] = x1[i] * x2[i];
	}
	fft(x1,len,-1);
	for(int i = 0;i < len; ++i) {
		sum[i] = int(x1[i].x + 0.5);
	}
	
	for(int i = 1;i <= mx; ++i) {
		bool ok = 0;
		for(int j = i;j <= mx;j += i) {
			ok |= (sum[j] > 0);
		}
		if(!ok) {
			cout << i << endl;
			break;
		}
	}
	
	return 0;
}

原文地址:https://www.cnblogs.com/akoasm/p/15132766.html