Đánh giá tháp điện mô-đun


13

Cho hai số n và m, đánh giá tháp năng lượng vô hạn:

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

Hãy nhớ rằng ^ là liên kết đúng. Vậy 2 ^ 3 ^ 4 = 2 ^ (3 ^ 4). Bây giờ làm thế nào bạn có thể gán một giá trị cho một chuỗi vô hạn các toán tử liên kết phải?

Xác định f (n, m, i) là tháp năng lượng chứa các điều khoản i đầu tiên của tháp năng lượng vô hạn. Sau đó, có một số hằng số C sao cho với mọi i> C, f (n, m, i) = f (n, m, C). Vì vậy, bạn có thể nói tháp năng lượng vô hạn hội tụ trên một giá trị nhất định. Chúng tôi quan tâm đến giá trị đó.


Chương trình của bạn phải có khả năng tính n = 2017, m = 10 ^ 10 trong dưới 10 giây trên PC hiện đại hợp lý. Đó là, bạn nên thực hiện một thuật toán thực tế, không có bruteforcing.

Bạn có thể giả sử rằng n <2 30m <2 50 cho các giới hạn số trong ngôn ngữ lập trình của bạn, nhưng về mặt lý thuyết, thuật toán của bạn phải hoạt động với mọi kích thước n , m . Tuy nhiên, chương trình của bạn phải chính xác cho các đầu vào trong các giới hạn kích thước này, tràn giá trị trung gian không được miễn trừ nếu các đầu vào nằm trong các giới hạn này.

Ví dụ:

2, 10^15
566088170340352

4, 3^20
4

32, 524287
16

Mẹo (đối với ứng cử viên): nmđang không đảm bảo được đồng thủ.
Leaky Nun

1
10 ^ 10 (và 10 ^ 20 và có khả năng 3 ^ 20 cho số nguyên đã ký) lớn hơn các loại số nguyên mặc định của nhiều ngôn ngữ. Có yêu cầu rằng đầu vào lớn này được hỗ trợ không?
Doorknob

1
@orlp "Có" bao gồm 10 ^ 20 không? Bởi vì điều đó không phù hợp với số nguyên 64 bit, vì vậy nếu bạn muốn yêu cầu nó, tôi khuyên bạn nên chỉ ra một cách rõ ràng, bởi vì nếu không, bạn sẽ nhận được rất nhiều câu trả lời không hợp lệ bởi mọi người chỉ cho rằng 64 bit số nguyên sẽ đủ chính xác.
Martin Ender

1
Dù bằng cách nào, những gì đầu vào lớn nhất chúng ta cần phải hỗ trợ?
Martin Ender

@Doorknob Tôi đã thêm giới hạn khoan dung hơn cho thử thách. Tuy nhiên, về mặt lý thuyết, thuật toán của bạn phải hoạt động với mọi kích thước m, n .
orlp

Câu trả lời:


7

Bình thường, 23 byte

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

Xác định hàm g, lấy mn theo thứ tự đó.

Dùng thử trực tuyến

Làm thế nào nó hoạt động

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 byte

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

Hãy thử trực tuyến!

Tại sao nó hoạt động

Chúng tôi sử dụng khái quát hóa sau đây của định lý Euler .

Bổ đề. n 2φ ( m )n ( m ) (mod m ) với mọi n (có hay không n là số nguyên tố của m ).

Chứng minh: Cho tất cả các lũy thừa p k chia m ,

  • Nếu p chia n , sau đó vì φ ( m ) ≥ φ ( p k ) = p k - 1 ( p - 1) ≥ 2 k - 1k , chúng ta có n 2φ ( m ) ≡ 0 ≡ n φ ( m ) (mod p k ).
  • Nếu không, vì φ ( p k ) chia φ ( m ), Định lý Euler cho n 2φ ( m ) ≡ 1 ≡ n φ ( m ) (mod p k ).

Do đó, n 2φ ( m )n φ ( m ) (mod m ).

Hệ quả. Nếu k ≥ φ ( m ), sau đó n kn φ ( m ) + ( k mod φ ( m )) (mod m ).

Chứng minh: Nếu k ≥ 2φ ( m ), bổ đề cho n k = n 2φ ( m ) n k - 2φ ( m )n φ ( m ) n k - 2φ ( m ) = n k - φ ( m ) ( mod m ) và chúng tôi lặp lại cho đến khi số mũ nhỏ hơn 2φ ( m ).


Làm thế nào điều này xử lý trường hợp cơ sở và modulo không phải là nguyên tố cùng nhau? PS sympy có chức năng tổng.
orlp

@orlp Tôi đã thêm một bằng chứng. Không chắc chắn làm thế nào tôi bỏ lỡ sympy.totient.
Anders Kaseorg

Tôi thấy bây giờ Phương pháp tốt đẹp!
orlp

5

Haskell , 156 byte

(?)mất hai Integergiây và trả về một Integer, sử dụng như (10^10)?2017(thứ tự đảo ngược so với 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

Hãy thử trực tuyến! (Tôi đặt các trường hợp để kiểm tra trong tiêu đề lần này, vì chúng sử dụng ký hiệu lũy thừa.)

Thật kỳ lạ, trường hợp thử nghiệm chậm nhất không phải là trường hợp có giới hạn tốc độ (gần như ngay lập tức), mà là trường hợp 524287 ? 32, bởi vì 524287số nguyên tố lớn hơn nhiều so với xuất hiện trong các yếu tố của các trường hợp thử nghiệm khác.

Làm thế nào nó hoạt động

  • (x&m)yx^y `mod` m, hoặc mod điện, sử dụng lũy ​​thừa bằng bình phương.
  • n#plà hàm tổng Euler của n, giả sử nkhông có thừa số nguyên tố nhỏ hơn p.
    • mnvới tất cả các pyếu tố được chia ra.
    • Nếu có kcác yếu tố như vậy, thì tổng số phải lấy một yếu tố tương ứng (p-1)*p^(k-1), được tính như sau div(n*p-n)(p*m).
    • 1`max`...xử lý trường hợp nkhông thực sự chia hết p, điều này làm cho các đối số khác maxbằng 0.
  • Hàm chính m?nsử dụng khi yđủ lớn, n^y `mod` mgiống như n^(t+(y`mod`t)) `mod` mkhi nào tlà tổng của m. (Điều t+cần thiết cho những yếu tố chính đó nmcó điểm chung, tất cả đều được tối đa hóa.)
  • Thuật toán dừng lại vì các hàm tổng số lặp đi lặp lại cuối cùng đạt 1.

1

Toán học, 55 byte

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

Ví dụ:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.