第二个是解的大小的问题,注意到递归过程中所有 x 的乘积不超过 c ,那么最终结果的级别是 O(c) 的,看起来有可能会超过 10^{2000} ,但由于完全跑不满因此不会。
Code 1
from math import gcd
def solve(a,b,c):
x=gcd(b,c)
if x==1:
return 0
return solve(a*x,a+b,c//x)*x+1
for i in range(int(input())):
a,b,c=map(int,input().split())
if gcd(a,gcd(b,c))>1:
print(-1)
continue
print(solve(a,b,c))
但是这道题直接从小到大枚举 n 或者随机化就可以过。虽然不会严谨的时间复杂度,但是是可以感性理解一下的。
具体来说,关键在于一个数的不同素因子的个数是在 O(\log c) 级别的,考虑用 c 的素因子个数对 n 的最小解进行感性分析。对于一个最小解 n',也就是说 \forall n<n',\gcd(an+b,c)>1 ,取一个数 s 和素数 t 满足 s+t<n' ,假设 p|\gcd(sa+b,c),q|\gcd((s+t)a+b,c) ,如果 p=q ,那么有 p|ta ,明显 p\not|a ,否则 \gcd(a,b,c)>1 ,所以有 p|t ,限制 t 为素数,那么就有 p=t ,也就是说有 t|c 。
上述分析感性说明一下,就是对于一个间隔为素数的不满足条件的 n ,要么 p\neq q ,这样 c 就会分析出两个不同的素因子,要么 p=q ,这样这个间隔就是 c 的素因子,由于 c 的素因子本来就不会很多, n' 足够大时其中每一种素数间隔都会至少贡献一种不同的质因子,大胆猜测 n 的最小解也会是 O(\log c) 级别的,基于同样的思想我们也可以猜测随机化也只会期望猜 O(\log c) 次。
当然,上述只是一个非常不严谨的对最小解大小的猜测式的分析,大家看一看就行了。
Code 2
from math import gcd
for i in range(int(input())):
a,b,c=map(int,input().split())
if gcd(a,gcd(b,c))>1:
print(-1)
continue
n=0
while gcd(a*n+b,c)>1:
n=n+1
print(n)