Dados dos números n y m, evalúe la torre de energía infinita:
n ^ (n + 1) ^ (n + 2) ^ (n + 3) ^ (n + 4) ^ ... mod m
Tenga en cuenta que ^ es asociativo correcto. Entonces 2 ^ 3 ^ 4 = 2 ^ (3 ^ 4). Ahora, ¿cómo puede asignar un valor a una secuencia infinita de operadores asociativos a la derecha?
Defina f (n, m, i) como la torre de energía que contiene los primeros términos i de la torre de energía infinita. Entonces hay una constante C tal que para cada i> C, f (n, m, i) = f (n, m, C). Entonces se podría decir que la torre de energía infinita converge en un cierto valor. Estamos interesados en ese valor.
Su programa debe poder calcular n = 2017, m = 10 ^ 10 en menos de 10 segundos en una PC moderna razonable. Es decir, debe implementar un algoritmo real, sin fuerza bruta.
Es posible suponer que n <2 30 y m <2 50 para los límites numéricos en su lenguaje de programación, pero su algoritmo debe teóricamente trabajo para cualquier tamaño n , m . Sin embargo, su programa debe ser correcto para las entradas dentro de estos límites de tamaño, los desbordamientos de valores intermedios no están justificados si las entradas están dentro de estos límites.
Ejemplos:
2, 10^15
566088170340352
4, 3^20
4
32, 524287
16
fuente
n
ym
se no garantiza que sea co-prime.Respuestas:
Pyth, 23 bytes
Define una función
g
, teniendo m y n en ese orden.Pruébalo en línea
Cómo funciona
Python 2,
10976 bytesPruébalo en línea!
Por que funciona
Utilizamos la siguiente generalización del teorema de Euler .
Lema n 2φ ( m ) ≡ n φ ( m ) (mod m ) para todos los n (independientemente de si n es coprime para m ).
Prueba: para todas las potencias primarias p k dividiendo m ,
Por lo tanto, n 2φ ( m ) ≡ n φ ( m ) (mod m ).
Corolario. Si k ≥ φ ( m ), entonces n k ≡ n φ ( m ) + ( k mod φ ( m )) (mod m ).
Prueba: si k ≥ 2φ ( m ), el lema da n k = n 2φ ( m ) n k - 2φ ( m ) ≡ n φ ( m ) n k - 2φ ( m ) = n k - φ ( m ) ( mod m ) y repetimos hasta que el exponente sea menor que 2φ ( m ).
fuente
sympy.totient
.Haskell , 156 bytes
(?)
toma dosInteger
sy devuelve unInteger
, usar como(10^10)?2017
(orden inverso en comparación con OP).Pruébalo en línea! (Esta vez pongo los casos a prueba en el encabezado, ya que usan la notación de exponenciación).
Curiosamente, el caso de prueba más lento no es el que tiene un límite de velocidad (que es casi instantáneo), sino el
524287 ? 32
uno, porque524287
es un primo mucho mayor que el que aparece en los factores de los otros casos de prueba.Cómo funciona
(x&m)y
esx^y `mod` m
, o mod de potencia, usando exponenciación al cuadrado.n#p
es la función totient de Eulern
, suponiendo quen
no tenga factores primos más pequeños quep
.m
Esn
con todos losp
factores divididos.k
tales factores, el cliente mismo debería obtener un factor correspondiente(p-1)*p^(k-1)
, que se calcula comodiv(n*p-n)(p*m)
.1`max`...
maneja el caso donde enn
realidad no era divisible porp
, lo que hace que el otro argumento seamax
igual a0
.m?n
utiliza que cuandoy
es lo suficientemente grande,n^y `mod` m
es lo mismo quen^(t+(y`mod`t)) `mod` m
, cuandot
es el total dem
. (t+
Es necesario para esos factores primosn
ym
tienen en común, que todos se maximizan).fuente
Mathematica, 55 bytes
Ejemplos:
fuente
Pari / GP , 59 bytes
Pruébalo en línea!
fuente