¿Por qué mi solución C ++ al problema SPOJ.com – Problema DIVSUM2 muestra un error?

La declaración del problema dice que hay 500 casos de prueba, cada uno con un número entero entre 1 y 1e16 inclusive

1e16 es un gran número. Si no tienes idea de qué tan grande es, déjame mostrarte:

10,000,000,000,000,000

Las CPU tienen una velocidad de reloj del orden de unos pocos GigaHertz. Es decir, la CPU moderna puede ejecutar alrededor de mil millones de ciclos de CPU por segundo. Suponiendo que en el mejor de los casos, 1 instrucción consume 1 ciclo de CPU, podemos decir que la CPU puede ejecutar del orden de mil millones de instrucciones por segundo.

Su código está haciendo operaciones de división 1e16. Asumiendo que una operación de división toma ~ 10 ciclos de CPU, su código consumirá 1e17 ciclos de CPU, que son aproximadamente 1e8 segundos. Esto es más de 3 años de tiempo. ¿Ves a dónde me dirijo?

Eso sí, eso es solo 1 caso de prueba. Tienes 500 de ellos.

Hablando algorítmicamente, su algoritmo es exponencial en complejidad (exponencial en el número de bits en la entrada). Necesita encontrar un mejor algoritmo para este problema.

Su programa excede el límite de tiempo.
Puede intentar optimizar su solución O (n) a O (sqrt (n)) mediante una simple observación de la siguiente manera.

Considere que el número dado es 24. Su código itera 24 veces para encontrar los factores 1,2,3,4,6,8,12 y 24.
Como puedes observar 24 = 8 × 3 = 3 × 8.
Entonces, en lugar de iterar 24 veces, puede ir hasta ceil (sqrt (24)) ~ 5 y resumir para (supongamos que la variable iteradora es i) i + (n / i). Además, trate de verificar si hay casos de esquina y AC.

24 es un número bastante pequeño. Solo imagine el tiempo de ejecución para un gran número como 1,000,000 en el que su solución iteraría 1000,000 veces y utilizando el método anterior puede obtener la respuesta en solo 1000 iteraciones.

PD: implementé el método anterior y obtuve un AC.

La razón por la que obtiene un TLE es porque iterar a través de cada número antes de que el número dado no sea simplemente lo suficientemente rápido.

El mejor enfoque es expresar el número en términos de factores primos, luego encontrar cada factor y luego evaluar la suma.

Por ejemplo, el número 24 se puede representar como 2 ^ 3 * 3.

Luego encuentre todos los factores, a saber, 2,3, 2 * 3, 2 * 2, 2 * 2 * 3, 2 * 2 * 2 y agréguelos.

Espero eso ayude

Me enfrenté a un problema similar cuando intentaba resolver un problema de codechef similar. El operador de extracción que utiliza c ++ consume bastante tiempo. Use scanf en su lugar. Puede pensar que no es C ++ pero está bien … pruébelo