所以我编写了一个程序(见下文)来运行一系列测试用例,并针对每种情况使用Euler's Criterion确定是否存在A≡X^ 2(modM)的X.它适用于小型测试用例,例如当A = 0且M = 2或A = 4且M = 7时,但当我考虑更大的测试用例时,例如当A = 83715323和M = 118299443时,程序就会挂起在第15行(如下所示)。为什么这个程序挂起?这是python的限制吗?我可能只是用C ++重做它吗?
问题专栏
if((A[case]**((M[case] - 1)/2) - 1) % M[case]) == 0:
整个计划
number_of_cases = int(raw_input())
A = []
M = []
for case in range(number_of_cases):
A_M = raw_input().split()
A.append(int(A_M[0]))
M.append(int(A_M[1]))
for case in range(number_of_cases):
solution_exists = 0
if((A[case]**((M[case] - 1)/2) - 1) % M[case]) == 0:
print ("YES")
break
else:
print("NO")
答案 0 :(得分:4)
A[case]**((M[case] - 1)/2) - 1)
计算的整数可以非常快地变大。使用任何语言计算这个数字需要花费大量的时间和内存。
相反,利用Python的pow
运算符及其第三个参数,它允许有效的模幂运算。
尝试更改
if((A[case]**((M[case] - 1)/2) - 1) % M[case]) == 0:
到
if pow(A[case], (M[case] - 1)/2 - 1, M[case]) == 0:
此处不计算大数A[case]**((M[case] - 1)/2) - 1)
:Python逐渐递增幂并在每一步跟踪模M[case]
的余数。
答案 1 :(得分:2)
您正在执行modular exponentiation。
因此,您不需要在一个声明中计算A[case]**((M[case] - 1)/2)
。这可能是导致你挂起的原因。
使用
这一事实x**(n) % m == {(x**(n-1) % m) * x} % m
即。你可以计算任意大n的x^n
的余数而不直接计算x^n
,然后乘以重复得到余数。
尝试分解指数(请参阅维基文章的" Memory-efficient method"部分),看看它是否仍然很慢。
我的赌注是它不是。