miércoles, 1 de junio de 2011

Divisor Summation

 Given a natural number n (1 <= n <= 500000), please output the summation of all its proper divisors.

Definition: A proper divisor of a natural number is the divisor that is strictly less than the number.

e.g. number 20 has 5 proper divisors: 1, 2, 4, 5, 10, and the divisor summation is: 1 + 2 + 4 + 5 + 10 = 22.

Input

An integer stating the number of test cases (equal to about 200000), and that many lines follow, each containing one integer between 1 and 500000 inclusive.
Output

One integer each line: the divisor summation of the integer given respectively. 


Example
Sample Input:
3
2
10
20

Sample Output:
1
8
22


https://www.spoj.pl/problems/DIVSUM/ 



public class DivisorSummation 
{
   public static void main( String args[] ) throws Exception
   {
      // Almacena la suma de los divisores para cada numero de 1 hasta 500000
      int[] sumDivisores = new int[ 500001 ];
      sumDivisores[ 1 ] = -1;
  
      int multiplo, factor;
  
      /*
      * En cada posicion del vector acumulamos la suma de divisores de dicha
      * posicion. Para eso tenemos en cuenta de que si:
      * A divide a X, entonces A y X/A son divisores de X, por lo tanto sumamos
      * A y X/A a sumDivisores[ X ], pero si A = X/A, solo sumamos A a sumDivisores[ X ]
      * ya que sino estariamos sumando 2 veces un mismo divisor.
      * Solo es necesario iterar desde 2 hasta la raiz cuadradada de 500000
      */
      for( int num = 2; num <= 707; num ++ )
      {
         multiplo = num * num;
         sumDivisores[ multiplo ] += num;
   
         for(  multiplo += num, factor = num + 1; multiplo <= 500000; multiplo += num, factor ++ )
            sumDivisores[ multiplo ] += ( num + factor );
      }
  
      //  Tamanio del buffer de salida
      int tamanio = 0;
      String cadena;
      int longitud, numero;
  
      // Numero de casos a procesar
      int numCasos = sig();
  
      // Buffer de salida, creada con un tamanio adecuado
      char[] salida = new char[  numCasos * 6 ];
  
      for( int i = 0; i < numCasos; i ++ )
      {
         numero = sig();
   
         cadena = ( sumDivisores[ numero ] + 1 ) + "\n";
         longitud = cadena.length();
   
         // Anadimos la cadena al buffer de salida
         cadena.getChars( 0, longitud, salida, tamanio );
         tamanio = tamanio + longitud;
      }
  
      System.out.print( new String( salida, 0, tamanio ) );
   }
 
   public static int sig() throws Exception
   {
      int car = System.in.read();
      int val = 0;
  
      while( car != 10 )
      {
         val = val * 10 + ( car - 48 );
         car = System.in.read();
      }
   
      return val;
   }
}

No hay comentarios:

Publicar un comentario