/****************************************************************************/
/* Función sigma(n), suma de los divisores de n.                            */
/* Funcion tau(n), número de divisores de n.                                */
/*                                                                          */
/* Jaime Suarez <mcripto@bigfoot.com> 2003                                  */
/* en http://elparaiso.mat.uned.es                                            */
/****************************************************************************/

#include <math.h>
#include <stdio.h>

typedef unsigned long ulong;
ulong sigma(ulong n);
ulong tau(ulong n);

int main(int argc, char *argv[])
{
	int i;
	ulong n;

	if (argc==1) {
		printf("Uso: %s n1 [n2] ...[nk]\n",argv[0]);
		printf("calcula cuántos divisores tiene un número\n");
		printf("y la suma de dichos divisores.\n");
		return 1;
	}
	for (i=1; i<argc; i++) {
		n= (ulong)atol(argv[i]);
		printf("%ld tiene %ld divisores que suman %ld.\n",
			n,tau(n),sigma(n));
	}
	
	return 0;
}

/*
 *  sigma(n) : suma de los divisores de n
 */

ulong sigma(ulong n)
{
	ulong p,e;
	float s;

	s=1.0;
	if ((float)n/2 == n/2) {
		e=0;	
		while ((float)n/2 == n/2) { n/=2; e++; }
		s *= (pow(2, e+1)-1)/(float)(2-1);
	}
	
	for (p=3; p*p<=n; p+=2) {
		if ((float)n/p == n/p) {
			e=0;
			while ((float)n/p == n/p) {n/=p; e++;}
			s *= (pow(p, e+1)-1)/(float)(p-1);
		}
	}
	if (n!=1) s *= (n*n-1.0)/(n-1.0);

	return (ulong)s;
}

/*
 *  tau(n): número de divisores de n
 */

ulong tau(ulong n)
{
	ulong p,e,t;

	t=1.0;
	if ((float)n/2 == n/2) {
		e=0;	
		while ((float)n/2 == n/2) { n/=2; e++; }
		t *= (e+1);
	}
	
	for (p=3; p*p<=n; p+=2) {
		if ((float)n/p == n/p) {
			e=0;
			while ((float)n/p == n/p) {n/=p; e++;}
			t *= (e+1);
		}
	}
	if (n!=1) t *= 2;

	return t;
}