2019-2020PtrCampDay8-I.Euclid's Algorithm-数论
link:https://codeforces.com/gym/103261/problem/I
题意:给 \(k,d\),求 \(\{(a+d)^k-a^k|a\in \mathbb{N}\}\) 的 \(\gcd\),\(1\leq k,d\leq 10^{100}\).
来复读一下题解
对每个质因子 \(p\) 考虑其对答案的贡献(好像其实很合理)
\((a+d)^k-a^k=\sum_{i=1}^k \binom{k}{i} d^i a^{k-i}\),对于 \(\gcd\) 来说,\(p\) 的幂次取决于使得其幂次最小的 \(a\)
- (1)如果 \(p\) 不是 \(d\) 的因子,取 \(a=p\),则 \((a+d)^k-a^k\equiv d^k\not\equiv 0(\bmod p)\),对答案没有贡献
- (2)否则假设 \(d\) 中有 \(q_d\) 个 \(p\) 因子,\(k\) 中有 \(q_k\) 个 \(p\) 因子,同时为了使得幂次最小,我们不妨考虑 \(\gcd(a,p)=1\) 的那些 \(a\),那么对于每一项 \(\binom{k}{i}d^i a^{k-i}\) 而言,恰有 \(q_k-q_i+i\times q_d\) 个 \(p\) 因子
- 而 \(i\) 变大 \(1\) 之后,因子个数会先变多 \(q_d\) 个,而我们假设 \(p|d\),那么 \(q_d\geq 1\),而 \(q_i\) 可能不变,可能减少 \(1\)
- 对于大部分 \(q_d>1\) 情况来说,显然 \(p\) 因子个数只取决于第一项,因为每往后一项至少多一个 \(p\) 因子,肯定没法通过加法( \(p\) 进制下的进位)得到更多的 \(p\) 因子,因此 \(q_d>1\) 时质因子的贡献就是 \(q_k+q_d\).
- 而这里有一个魔鬼细节,对于 \(q_d=1\),\(i=1\to i=2\) 要想保持不变,必然有 \(q_1=0,q_2=1\),也就是只有 \(p=2\) 的情况是特殊的:此时这两项都是 \(q_k-0+1=q_k+1\) 和 \(q_k-1+2=q_k+1\) 个 \(p=2\) 的因子,往后也依然是这样,这时候至少有 \(q_k+2\) 个 \(p=2\) 因子
- 而这里又可以断言,其实至多也是 \(q_k+2\) 个 \(p=2\) 因子!!!因为考虑 \((a+2d)^k-a^k\) 有 \(q_k+1+1=q_k+2\) 个 \(p\) 因子,而它会等于 \([(a+2d)^k-(a+d)^k]+[(a+d)^k-a^k]\),右边是 \(q_d=1\) 的两个式子相加,如果其至少有 \(q_k+3\) 个 \(p\) 因子,左边则至少有 \(q_k+3\) 个 \(p\) 因子,这是矛盾的
综上,对每个 \(p\) 因子有两种case:
- 首先,必须要 \(p|d\) 才有贡献:、
- (1)一般情况是 \(q_k+q_d\) 的贡献
- (2)特殊的,\(p=2\),\(q_d=1\),则幂次是 \(q_k+2\)
然后我们去写一发,发现wa了,为什么呢…
(2)里面还有bug…如果 \(k\) 刚刚好是 \(2\),\((a+d)^2 -a^2 =d(2a+d)\),答案应该直接是 \(d\times \gcd(2,d)\),在一些情况下会和上面说的不一样(具体地,\(p=2,q_d=1\) 时),因为但为什么会出现这种情况呢…这时候对应(2)的特殊情况,\(q_k=1\) 的话,
ChatGPT写的Python代码:
import math
import sys
def main():
d, k = map(int, sys.stdin.read().split())
if k==2:
print(math.gcd(k,d)*d)
return
qd, qk = 0, 0
while d % 2 == 0:
d //= 2
qd += 1
while k % 2 == 0:
k //= 2
qk += 1
ans = d * math.gcd(pow(d, 332), k)
if qd == 1:
ans *= 2 ** (qk + 2)
elif qd!=0:
ans *= 2 ** (qk + qd)
print(ans)
if __name__ == "__main__":
main()