Оцініть модульні енергетичні вежі


13

Давши два числа n і m, оцініть нескінченну потужність вежі:

n ^ (n + 1) ^ (n + 2) ^ (n + 3) ^ (n + 4) ^ ... mod m

Майте на увазі, що ^ право-асоціативний. Отже 2 ^ 3 ^ 4 = 2 ^ (3 ^ 4). Тепер, як ви, можливо, можете призначити значення нескінченній послідовності право-асоціативних операторів?

Визначте f (n, m, i) як енергетичну вежу, що містить перші i члени нескінченної енергетичної вежі. Тоді існує деяка константа C така, що для кожного i> C, f (n, m, i) = f (n, m, C). Тож можна сказати, що нескінченна башта потужності сходить на певне значення. Нас цікавить ця цінність.


Ваша програма повинна мати можливість обчислити n = 2017, m = 10 ^ 10 за 10 секунд на розумному сучасному ПК. Тобто, ви повинні реалізувати власне алгоритм, а не грубої сили.

Ви можете припустити, що n <2 30 та m <2 50 для числових обмежень у вашій мові програмування, але ваш алгоритм повинен теоретично працювати для будь-якого розміру n , m . Однак ваша програма повинна бути правильною щодо введення даних у межах цих розмірів, проміжні значення переливів не виправдовуються, якщо входи знаходяться в цих межах.

Приклади:

2, 10^15
566088170340352

4, 3^20
4

32, 524287
16

Рада (для претендентів): nі mякі НЕ гарантовані спільно прем'єра.
Leaky Nun

1
10 ^ 10 (і 10 ^ 20, і потенційно 3 ^ 20 для підписаних цілих чисел) більше, ніж цілі типи за багатьма мовами за замовчуванням. Чи потрібно підтримувати цей великий вхід?
Дверна ручка

1
@orlp Чи означає, що це "так" включає 10 ^ 20? Оскільки це не вписується в 64-бітове ціле число, тому, якщо ви хочете його вимагати, я б запропонував його чітко вказати, тому що в іншому випадку ви отримаєте багато невірних відповідей людей, тільки припускаючи, що 64 біт цілі числа будуть досить точними.
Мартін Ендер

1
У будь-якому випадку, то , що це найбільший вхід , ми повинні підтримувати?
Мартін Ендер

@Doorknob Я додав більш м'які обмеження до виклику. Однак ваш алгоритм повинен теоретично працювати для будь-якого розміру m, n .
orlp

Відповіді:


7

Pyth, 23 байти

M&tG.^HsgBu-G/GH{PGGhHG

Визначає функцію g, приймаючи m і n у цьому порядку.

Спробуйте в Інтернеті

Як це працює

M&tG.^HsgBu-G/GH{PGGhHG
M                         def g(G, H):
 &tG                        0 if G == 1, else …
                 PG         prime factors of G
                {           deduplicate that
          u-G/GH   G        reduce that on lambda G,H:G-G/H, starting at G
                              (this gives the Euler totient φ(G))
        gB          hH      bifurcate: two-element list [that, g(that, H + 1)]
       s                    sum
    .^H               G     H^that mod G

Python 2, 109 76 байт

import sympy
def g(n,m):j=sympy.totient(m);return m-1and pow(n,j+g(n+1,j),m)

Спробуйте в Інтернеті!

Чому це працює

Ми використовуємо наступне узагальнення теореми Ейлера .

Лема n 2φ ( m )n φ ( m ) (mod m ) для всіх n (незалежно від того, чи n є одночасно m ).

Доведення: для всіх простих сил p k, що ділить m ,

  • Якщо p ділить n , то тому, що φ ( m ) ≥ φ ( p k ) = p k - 1 ( p - 1) ≥ 2 k - 1k , маємо n 2φ ( m ) ≡ 0 ≡ n φ ( m ) (mod p k ).
  • В іншому випадку, оскільки φ ( p k ) ділить φ ( m ), теорема Ейлера дає n 2φ ( m ) ≡ 1 ≡ n φ ( m ) (mod p k ).

Тому n 2φ ( m )n φ ( m ) (mod m ).

Наслідок Якщо k ≥ φ ( m ), то n kn φ ( m ) + ( k mod φ ( m )) (mod m ).

Доведення: Якщо k ≥ 2φ ( m ), лемма дає n k = n 2φ ( m ) n k - 2φ ( m )n φ ( m ) n k - 2φ ( m ) = n k - φ ( m ) ( mod m ) і повторюємо, поки показник не стане меншим 2φ ( m ).


Як це поводиться у випадку, коли база та модуль не є копрієм? PS-симпатія має загальну функцію.
orlp

@orlp Я додав доказ. Не впевнений, як я сумував sympy.totient.
Anders Kaseorg

Я зараз бачу. Гарний метод!
orlp

5

Haskell , 156 байт

(?)займає два Integerс і повертає Integer, використовувати як (10^10)?2017(зворотний порядок порівняно з ОП.)

1?n=0
m?n=n&m$m#2+m#2?(n+1)
1#_=1
n#p|m<-until((<2).gcd p)(`div`p)n=m#(p+1)*1`max`div(n*p-n)(p*m)
(_&_)0=1
(x&m)y|(a,b)<-divMod y 2=mod(x^b*(mod(x*x)m&m)a)m

Спробуйте в Інтернеті! (Цього разу я ставив випадки для тестування у заголовку, оскільки вони використовують позначення експоненції.)

Цікаво, що найповільніший тестовий випадок - це не той, який має обмеження швидкості (це майже миттєво), а той 524287 ? 32, тому що 524287це набагато більший прайм, ніж з'являється в факторах інших тестових випадків.

Як це працює

  • (x&m)yє x^y `mod` m, або power mod, використовуючи експоненцію шляхом квадратування.
  • n#pє тотальною функцією Ейлера n, припускаючи, що він nмає не менші прості коефіцієнти, ніж p.
    • mце nз усіма pчинниками.
    • Якщо є kтакі фактори, тотіент повинен сам отримати відповідний коефіцієнт (p-1)*p^(k-1), який розраховується як div(n*p-n)(p*m).
    • 1`max`...обробляє випадок, коли nнасправді не було поділено на p, що робить інший аргумент maxрівним 0.
  • Основна функція m?nвикористовує те, що, коли yє достатньо великим, n^y `mod` mє тим самим n^(t+(y`mod`t)) `mod` m, що і коли tє коефіцієнт m. ( t+Потрібно для тих головних факторів nі mмають спільне, що всі отримують максимум.)
  • Алгоритм зупиняється, оскільки ітералізовані функції тотієнта врешті-решт потрапляють на 1.

1

Математика, 55 байт

n_~f~1=0;n_~f~m_:=PowerMod[n,(t=EulerPhi@m)+f[n+1,t],m]

Приклади:

In[1]:= n_~f~1=0;n_~f~m_:=PowerMod[n,(t=EulerPhi@m)+f[n+1,t],m]

In[2]:= f[2, 10^15]

Out[2]= 566088170340352

In[3]:= f[4, 3^20]

Out[3]= 4

In[4]:= f[32, 524287]

Out[4]= 16

In[5]:= f[2017, 10^10]

Out[5]= 7395978241

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.