モジュラーパワータワーの評価


13

2つの数値nとmが与えられた場合、無限の電力塔を評価します。

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

^は右結合であることに注意してください。したがって、2 ^ 3 ^ 4 = 2 ^(3 ^ 4)。さて、どうやって値を右連想演算子の無限シーケンスに割り当てることができますか?

f(n、m、i)を、無限の電力塔の最初のi項を含む電力塔として定義します。次に、i> Cごとにf(n、m、i)= f(n、m、C)のような定数Cがあります。したがって、無限の電力塔は特定の値に収束すると言えます。その価値に興味があります。


プログラムは、合理的な最新のPCで10秒未満でn = 2017、m = 10 ^ 10を計算できる必要があります。つまり、ブルートフォーシングを行わずに、実際のアルゴリズムを実装する必要があります。

プログラミング言語の数値制限については、n <2 30およびm <2 50であると想定できますが、アルゴリズムは理論的には任意のサイズnmで機能する必要があります。ただし、プログラムこれらのサイズ制限内の入力に対して正しくなければなりません。入力がこれらの制限内であれば、中間値のオーバーフローは許さません

例:

2, 10^15
566088170340352

4, 3^20
4

32, 524287
16

ヒント(候補者向け):nそして、互いに素であるとm限りません。
リーキー修道女

1
10 ^ 10(および10 ^ 20、および符号付き整数の場合は3 ^ 20)は、多くの言語のデフォルトの整数型よりも大きくなります。この大規模な入力をサポートする必要がありますか?
ドアノブ

1
@orlp「はい」には10 ^ 20が含まれますか?それは64ビット整数に収まらないため、必要な場合は明示的に指摘することをお勧めします。整数は十分正確です。
マーティンエンダー

1
どちらにしても、サポートする必要ある最大の入力は何ですか?
マーティンエンダー

@Doorknobチャレンジにもっと寛大な制限を追加しました。ただし、アルゴリズムは任意のサイズm、nに対して理論的に機能する必要があります。
orlp

回答:


7

Pyth、23バイト

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

関数を定義し、mnをこの順序gで取ります。

オンラインで試す

使い方

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φ(MN φ(M(MOD Mすべてについて)N(かどうかNに互いに素であるM)。

証明:mを除算するすべての素数p kに対して

  • もしp個の分割nは、次いでためφM)≥ φP 、K)= PのK 1 - P - 1)≥2 K - 1つのK、我々はN 2φ(M ≡0≡ N φ(M(mod p k)。
  • そうでなければ、ためφPのK)分割φM)、オイラーの定理が得られるN 2φ(M ≡1≡ N φ(M(MOD のp K)。

したがって、N 2φ(MN φ(M(MOD M)。

当然。もしK ≥φ(M)、次いでN k個N φ(M)+(K MODφ(M))(MOD M)。

証明:もしK ≥2φ(M)、補題を与えるN K = N 2φ(MN K - 2φ(MN φ(Mnは K - 2φ(M = N K - φ(M( mod m)そして、指数が2φ( m)未満になるまで繰り返します。


これは、ベースとモジュロが互いに素でない場合をどのように処理しますか?PS sympyにはtotient機能があります。
-orlp

@orlp証拠を追加しました。どうして逃したのか分からないsympy.totient
アンダースカセオルグ

なるほど。いい方法!
orlp

5

Haskell、156バイト

(?)2つIntegerのsを受け取りInteger、を使用します(10^10)?2017(OPと比較して逆順)。

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

オンラインでお試しください!(今回は、べき乗表記法を使用しているため、テストするケースをヘッダーに入れました。)

不思議な最も遅いテストケースは(ほとんど瞬時'S)速度制限を有するものではなく、524287 ? 32一ため524287他のテストケースの要因に現れるよりもはるかに大きい素数です。

使い方

  • (x&m)yx^y `mod` m、または乗法によるべき乗を使用した累乗modです。
  • n#p は、オイラーのtotient関数です。 nと仮定すると、nよりも小さい素因数を有していませんp
    • mnすべてと一緒ですp要因が出て分割。
    • ある場合 kような要因、totient自体が対応する要因を取得する必要(p-1)*p^(k-1)がありますdiv(n*p-n)(p*m)。これはとして計算されます。
    • 1`max`...はでn割り切れないケースを処理しpます。max0ます。等しくなります。
  • メイン関数m?nは、when yが十分に大きい場合n^y `mod` m、と同じでn^(t+(y`mod`t)) `mod` m、when tがtotientである場合に使用しますmます。(t+これらの素因数nm、すべての最大化を取得され、共通しています。)
  • 反復されたtotient関数が最終的に1をヒットするため、アルゴリズムは停止します。

1

Mathematica、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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.