2021牛客暑期多校训练营1
H-Hash Function
给定一个长度为\(n\)的数组\(a\),每个元素互不相同,请你求出最小的\(p\),使得每个元素对\(p\)取模后互不相同。
可以发现,如果要满足题目所给条件,那么对于任意两个元素\(a_i\),\(a_j\),必须不满足\(a_i-a_j\equiv0(mod~p)\)。
我们先考虑如何求出所有的\(a_i+a_j\):
对于每个数\(i\),如果它出现的次数为\(j\),那么我们就让多项式的第\(j\)项系数为\(i\),就是\(i \cdot x^j\)。
比如\(a\)为\(2\),\(3\),\(4\),那么多项式就为\(f(x)=1 \cdot x^4 + 1 \cdot x^3 + 1 \cdot x^2 + 0 \cdot x^1 + 0 \cdot x^0\)。
然后我们对\(f(x)\)和它本身跑一遍\(NTT\)就会得到:
\(g(x)=1 \cdot x^ 8 + 2 \cdot x^7 + 3 \cdot x^6 + 2 \cdot x^5 + 1 \cdot x^4 + 0 \cdot x^3 + 0 \cdot x^2 + 0 \cdot x^1 + 0 \cdot x^0\)。
\(i \cdot x^j\)就代表和为\(j\)的对数有\(i\)对。
然后我们考虑如何求\(a_i-a_j\),我们只需要将上述\(a_j\)替换为\(MAXN-a_j(MAXN\geq 5\cdot10^5)\),然后构造新的\(F(x)\)和\(f(x)\)进行\(NTT\)即可,那么求出来的就是\(a_i+MAXN-a_j\)的对数,那么对于\(i \cdot x^j\)我们只需要让\(j-MAXN\),就是差为\(i\)的对数。
然后枚举答案即可。
#include <bits/stdc++.h>
using namespace std;
#define int long long
namespace NTT {
const int MAXN = 5e5 + 5;
const int MOD = 998244353;
const int G = 3;
template<typename T>
T fpow(T a, int n) {
T res = 1;
while (n) {
if (n & 1) {
res = (res * a) % MOD;
}
a = (a * a) % MOD;
n >>= 1;
}
return res;
}
int inv(int a) {
return fpow(a, MOD - 2);
}
struct Complex {
double x, y;
Complex(double _x, double _y): x(_x), y(_y) {}
Complex operator +(Complex oth) {
return Complex(x + oth.x, y + oth.y);
}
Complex operator -(Complex oth) {
return Complex(x - oth.x, y - oth.y);
}
Complex operator *(Complex oth) {
return Complex(x * oth.x - y * oth.y, x * oth.y + y * oth.x);
}
};
int R[MAXN << 2], L, limit = 1;
void NTT(int a[], int opt) {
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) {
int val = fpow(G, (MOD - 1) / (mid * 2));
if (opt == -1) val = inv(val);
for (int len = mid << 1, pos = 0; pos < limit; pos += len) {
for (int k = 0, w = 1; k < mid; ++k, w = w * val % MOD) {
int x = a[pos + k], y = w * a[pos + mid + k] % MOD;
a[pos + k] = (x + y) % MOD;
a[pos + k + mid] = (x - y + MOD) % MOD;
}
}
}
if (opt == 1) return;
int t = inv(limit);
for (int i = 0; i < limit; ++i) {
a[i] = a[i] * t % MOD;
}
}
void poly(int a[], int b[], int deg) {
while (limit <= deg) {
limit <<= 1, ++L;
}
for (int i = 0; i < limit; ++i) {
R[i] = (R[i >> 1] >> 1) | ((i & 1) << (L - 1));
}
NTT(a, 1);
NTT(b, 1);
for (int i = 0; i < limit; ++i) {
a[i] = a[i] * b[i] % MOD;
}
NTT(a, -1);
}
}; // namespace NTT
using NTT::poly;
const int MAXN = 5e5 + 5;
bool vis[MAXN];
int a[MAXN << 2], b[MAXN << 2];
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
int x;
cin >> x;
++a[x], ++b[MAXN - x];
}
poly(a, b, MAXN << 1);
// 枚举系数
for (int i = MAXN + 1; i <= MAXN + MAXN; ++i) {
if (a[i]) {
vis[i - MAXN] = true;
}
}
// 枚举答案
// 因为元素最大只有500000, 所以即使每个元素都不同, 答案最大也只有500001
for (int i = 1; i <= 500001; ++i) {
int j;
for (j = i; j <= 500000; j += i) {
// 如果数组中两个数的差值是i的倍数, 则不满足条件直接break
if (vis[j]) {
break;
}
}
if (j > 500000) {
cout << i << '\n';
break;
}
}
system("pause");
return 0;
}
原文地址:https://www.cnblogs.com/stler/p/15128551.html
- 运维工作中sed常规操作命令梳理
- linux下安装php的imagick扩展模块(附php升级脚本)
- 用JS + WCF打造轻量级WebPart
- Android之assets资源
- ExtJs学习笔记(24)-Drag/Drop拖动功能
- 人工智能尚处探索阶段,为何我们对此异常焦虑
- ExtJs学习笔记(22)-XTemplate + WCF 打造无刷新数据分页
- 同步服务器系统时间操作记录
- kvm虚拟化管理平台WebVirtMgr部署-完整记录(安装Windows虚拟机)-(4)
- ExtJs学习笔记(11)_Absolute布局和Accordion布局
- ExtJs学习笔记(9)_Window的基本用法
- DateTime在ExtJs中无法正确序列化的问题
- ELK实时日志分析平台环境部署--完整记录
- 梳理Linux下OSI七层网络与TCP/IP五层网络架构
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- volatile关键字在Android中到底有什么用?
- Python无头爬虫下载文件的实现
- Python基于stuck实现scoket文件传输
- Python %r和%s区别代码实例解析
- Python基础类继承重写实现原理解析
- python torch.utils.data.DataLoader使用方法
- Android自定义橡皮擦效果
- Android Canvas drawText文字居中的一些事(图解)
- Nginx+keepalived一主一从高可用,手把手带你一步一步配置!
- Behave!:一款针对页面活动的浏览器监控插件
- R可视化 | 地理信息空间(上)
- Nautilus:一款基于语法的反馈式模糊测试工具
- R可视化 | 地理信息空间(下)
- 21页优雅读博指南:佐治亚理工学院助理教授Eric Gilbert撰写,入坑前必读
- Too old resource version 引起 Flink JobManager 崩溃的问题定位