ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[牛客多校]第一场H.Hash Function

2021-09-16 03:33:20  阅读:137  来源: 互联网

标签:Function Hash int rev 牛客 seed 哈希 ans type


题意:定义哈希函数\(h_{seed}(x) = x \mod{seed}\),给定一个集合,要求找到一个最小的\(seed\),使得集合内的数字哈希函数两两不同。
数据范围:\(n\le 5\times 10^5, a_i\le 5\times 10^5\)

注意到两个数字的哈希函数当且仅当$seed | (a_i - a_j) \(,假如我们知道每一个\)(a_i -a _j)\(是否存在,我们枚举每个\)seed\(,然后判断\)seed\(的每个倍数是否存在,这个过程是\)O(nlogn)$的,因为调和级数。

于是问题变成怎么快速求出每个\((a_i - a_j)\)是否存在。

\(f(i)\)表示\(i\)是否存在,反转整个数组,变成\(g(x) = f(500000 - x)\),然后跟原数组卷积,我们发现卷积\(h(x) = \sum f(i) * f(50000 - x - i)\),\(f(i),f(50000 - x - i)\)都不为\(0\)的时候对数组有贡献,表示存在这样的一个\((a_i - a_j)\)。

于是NTT随便卷一下就行了。

#include <bits/stdc++.h>
#define pt(x) cout << x << endl;
#define Mid ((l + r) / 2)
#define lson (rt << 1)
#define rson (rt << 1 | 1)
using namespace std;
int read() {
	char c; int num, f = 1;
	while(c = getchar(),!isdigit(c)) if(c == '-') f = -1; num = c - '0';
	while(c = getchar(), isdigit(c)) num = num * 10 + c - '0';
	return f * num;
}
const int P = 998244353, G = 3, Gi = 332748118;
const int N = 5e5, M = N * 5 + 1009;
int n, A[M], B[M];
int Pow(int a, int p) {
	int ans = 1;
	for( ; p; p >>= 1, a = 1ll * a * a % P)
		if(p & 1)
			ans = 1ll * a * ans % P;
	return ans % P;
}
namespace Polynomial {
	const double Pi = acos(-1.0);
	int rev[M];
	template <typename T>
	void change(T *y, int n) {
		for(int i = 0; i < n; i++) 
			rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (n >> 1) : 0);
		for(int i = 0; i < n; i++) 
			if(i < rev[i])
				swap(y[i], y[rev[i]]);
	}
	void NTT(int *A, int n, int type) {
		//type = 1 DFT 
		//type = -1 IDFT 
		change(A, n);
		for(int m = 1; m < n; m <<= 1) {
			int Wn = Pow(type == 1 ? G : Gi, (P - 1) / (m << 1));
			for(int i = 0; i < n; i += 2 * m) {
				int w = 1;
				for(int j = 0; j < m; j++, w = 1ll * w * Wn % P) {
					int x = A[i + j], y = 1ll * w * A[i + j + m] % P;
					A[i + j] = (x + y) % P;
					A[i + j + m] = (x - y + P) % P;
				} 
			}
		}
		if(type == -1) {
			int inv = Pow(n, P - 2);
			for(int i = 0; i < n; i++)
				A[i] = 1ll * A[i] * inv % P;
		}
	}
	
}
int check(int x) {
	for(int i = x; i <= N; i += x) 
		if(A[i]) 
			return false;
	return true;
}
signed main()
{
	n = read();
	for(int i = 1; i <= n; i++) {
		int x = read();
		A[x] = 1;
		B[N - x] = 1;
	}
	int lim = 1;
	while(lim <= 2 * N) lim <<= 1;
	Polynomial :: NTT(A, lim, 1); 
	Polynomial :: NTT(B, lim, 1);
	for(int i = 0; i < lim; i++) A[i] = 1ll * A[i] * B[i] % P;
	Polynomial :: NTT(A, lim, -1); 
	reverse(A, A + 1 + N);
	int i = n;
	while(1) {
		if(check(i)) {
			printf("%d\n", i);
			return 0;
		}
		i++;
	}
	return 0;
}

标签:Function,Hash,int,rev,牛客,seed,哈希,ans,type
来源: https://www.cnblogs.com/onglublog/p/15291627.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有