CodeForces-1593D2 Half of Same

*CodeForces-1593D2 Half of Same

tag: *1900;数学,整除,枚举

给定长度为 \(n\) 的序列 \(a_1,\cdots,a_n\),其中 \(n\) 为偶数。求最大的正整数 \(k\),符合下述条件:

  • 执行任意次操作,每次操作选定一个 \(a_i\),将其减去 \(k\),最终使得序列 \(a\) 中至少一半的元素相等。

如果 \(k\) 可以任意大,输出 \(-1\)\(1\le t\le10\)\(4\le n\le40\)\(|a_i|\le10^6\)\(\sum n\le100\)

首先,\(k\) 可以任意大,当且仅当初始序列中就有一半以上的数相等。

如果确定了 \(k\),那么对每个数减去 \(k\),不改变对 \(k\) 取模的余数。换句话说,两个数可以变为相等当且仅当它们属于同一个模 \(k\) 的同余类。

同时,两个数 \(a,b\) 属于同一个模 \(k\) 的同余类,即 \(a\equiv b\pmod k\),当且仅当 \(k\mid a-b\)

注意到 \(n\) 很小,枚举 \(a_i,a_j\) 属于同一个同余类,那么 \(k\) 一定为 \(|a_i-a_j|\) 的约数,因此再从大到小枚举 \(|a_i-a_j|\) 的所有约数作为 \(k\),验证是否合法。时间复杂度 \(O(tn^3\sqrt A)\),其中 \(A\)\(a\) 的极差。

时间很紧,需要精细实现。具体来说,check 函数一定要传入使至少半个序列元素相等的那个值,即余数 \(r=|a_i-a_j|\bmod k\),然后直接数出 \(a_i\bmod k=r\) 的数量(而不是开个数组记录所有可能的同余类中元素数量,这样会很慢)。

注意负数取模写成 (a % MOD + MOD) % MODSubmission #344440231 - Codeforces

posted @ 2025-10-23 16:38  f2021ljh  阅读(4)  评论(0)    收藏  举报