Существуют более быстрые способы сделать это, основанные на факторизации n
и применении большого количества математики.Тем не менее, в качестве базового улучшения, которое идет от O(n)
до O(sqrt(n))
с использованием идеи гигантского шага "маленький шаг".Это также довольно просто по сравнению с альтернативой.
def multiplicative_order2(a, n):
if gcd(a, n) != 1:
return -1
visited = {}
count = 0
count = slow = fast = 1
while fast not in visited:
visited[slow] = count
count += 1
slow = (slow * a) % n
fast = (fast * slow) % n
return count * (count + 1) // 2 - visited[fast]