모듈 식 전력 타워 평가


13

두 개의 숫자 n과 m이 주어지면 무한 전력 타워를 평가하십시오.

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

^는 오른쪽 연관임을 명심하십시오. 따라서 2 ^ 3 ^ 4 = 2 ^ (3 ^ 4)입니다. 이제 어떻게 오른쪽 연관 연산자의 무한 시퀀스에 값을 할당 할 수 있습니까?

무한 전력 타워의 첫 번째 i 항을 포함하는 전력 타워로 f (n, m, i)를 정의하십시오. 그런 다음 모든 i> C, f (n, m, i) = f (n, m, C)에 대해 일정한 C가 있습니다. 따라서 무한 전력 타워가 특정 값으로 수렴한다고 말할 수 있습니다. 우리는 그 가치에 관심이 있습니다.


귀하의 프로그램은 합리적인 최신 PC에서 10 초 이내에 n = 2017, m = 10 ^ 10을 계산할 수 있어야합니다. 즉, 실제 알고리즘을 구현해야하며 무차별 처리하지 않아야합니다.

프로그래밍 언어의 숫자 제한에 대해 n <2 30m <2 50 이라고 가정 할 수 있지만 알고리즘은 이론적으로 모든 크기 n , m에서 작동해야합니다 . 프로그램이 그러나 한다 이 크기 한도 내에서 입력에 대한 정확, 중간 값 오버 플로우가되어 있지 입력이이 범위의 경우 면제.

예 :

2, 10^15
566088170340352

4, 3^20
4

32, 524287
16

(경쟁자에 대한) 팁 : nm되어 있지 공동 프라임 보장.
Leaky Nun

1
10 ^ 10 (및 10 ^ 20, 부호있는 정수의 경우 3 ^ 20)은 여러 언어의 기본 정수 유형보다 큽니다. 이 큰 입력을 지원해야합니까?
Doorknob

1
@orlp "yes"에 10 ^ 20이 포함되어 있습니까? 그것이 64 비트 정수에 맞지 않기 때문에 그것을 원한다면 명시 적으로 지적하는 것이 좋습니다. 그렇지 않으면 64 비트를 가정하는 사람들이 많은 잘못된 답변을 얻을 것이기 때문에 정수는 충분히 정확할 것입니다.
Martin Ender

1
어느 쪽이든, 우리가 지원해야 할 가장 큰 입력 무엇 입니까?
Martin Ender

@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

파이썬 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 k는N φ ( m ) + ( K 개조 φ ( 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 sympy에는 참을성있는 기능이 있습니다.
orlp

@orlp 나는 증거를 추가했습니다. 내가 어떻게 그리웠는지 모르겠다 sympy.totient.
Anders Kaseorg

나는 지금 본다. 좋은 방법!
orlp

5

하스켈 , 156 바이트

(?)Integer개의을 가져 와서를 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

온라인으로 사용해보십시오! (나는 지수 표기법을 사용하기 때문에 이번에는 헤더에서 사례를 테스트했습니다.)

흥미롭게도 가장 느린 테스트 사례는 속도 제한이있는 것이 아니라 (즉시 거의) 다른 테스트 사례의 요소보다 훨씬 큰 소수 524287 ? 32이기 때문 524287입니다.

작동 원리

  • (x&m)yx^y `mod` m제곱에 의한 지수를 사용하는, 또는 전력 모드입니다.
  • n#p보다 작은 소인수가 없다고 n가정 할 때 의 오일러 (Euler) 계급 함수입니다 . np
    • m입니다 n모두와 함께 p요소가 밖으로 나누었다.
    • 이있는 경우 k등의 요소는 totient 자체가 대응 가야 인자 (p-1)*p^(k-1)로서 계산된다 div(n*p-n)(p*m).
    • 1`max`...취급하는 경우 n로 나눌 수 없었다 실제로 p다른 인자하게, max같음을 0.
  • 주요 기능 m?ny충분히 클 때와의 때에 n^y `mod` m같은 것 입니다 . (이 주요 요소 에 필요하며 공통점이 있으며 모두 최대화됩니다.)n^(t+(y`mod`t)) `mod` mtmt+nm
  • 반복 된 강의 기능이 결국 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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.