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) % MOD。Submission #344440231 - Codeforces

浙公网安备 33010602011771号