¿Existe un algoritmo eficiente para calcular el entero N más pequeño de forma que N! es divisible por p^k donde p es un número primo relativamente pequeño y k, un número entero muy grande. En otras palabras,Algoritmo para encontrar el N más pequeño de forma que N! es divisible por un primado elevado a una potencia
factorial(N) mod p^k == 0
Si, dado N y P, que quería encontrar cuántas veces p divide en N !, me gustaría utilizar la conocida fórmula-
k = Sum(floor(N/p^i) for i=1,2,...
que he hecho La fuerza bruta busca valores pequeños de k, pero ese enfoque se rompe muy rápidamente a medida que k aumenta y no parece haber un patrón que pueda extrapolar a valores más grandes.
Editado 6/13/2011
partir de las sugerencias propuestas por fiver y Hammar, que utilizan una búsqueda cuasi binaria para resolver el problema, pero no del todo de la manera que sugirieron. Utilizando una versión truncada de la segunda fórmula anterior, calculé un límite superior en N como el producto de k y p (usando solo el primer término). Usé 1 como límite inferior. Usando el algoritmo de búsqueda binaria clásico, calculé el punto medio entre estos dos valores y calculé qué k estaría usando este valor de punto medio como N en la segunda fórmula, esta vez con todos los términos que se usan.
Si el k calculado era demasiado pequeño, ajusté el límite inferior y lo repetí. Demasiado grande, primero probé para ver si k calculado en el punto medio-1 era más pequeño que el k deseado. Si es así, se devolvió el punto medio como el N más cercano. De lo contrario, ajusté el punto alto y lo repetí.
Si los k calculados fueron iguales, probé si el valor en el punto medio-1 era igual al valor en el punto medio. Si es así, ajusté el punto alto para que fuera el punto medio y lo repitiera. Si el punto medio-1 era menor que el k deseado, el punto medio se devolvió como la respuesta deseada.
Incluso con valores muy grandes para k (10 o más dígitos), este enfoque funciona con velocidades O (n log (n)).
Aunque la respuesta de Nemo no es muy clara, creo que es mejor que la búsqueda binaria. ¡Después de todo, es O (1)! O, para ser más precisos, ya que tiene que manejar los dígitos, es O (log k). Este problema se puede resolver directamente, por lo que no es necesario realizar cálculos iterativos. – Fezvez
Es preferible responder a su propia pregunta, no como una edición de la pregunta. – ThomasMcLeod
"10 o más dígitos" no es "muy grande" :-). He editado mi respuesta para agregar una implementación de Perl. Parece funcionar bien incluso para k con docenas de dígitos, aunque no sé si la respuesta es correcta. Si puede encontrar un caso en el que da la respuesta incorrecta, me gustaría verlo. – Nemo