Cod sursa(job #916288)

Utilizator AndreiRSStatescu Andrei Rares AndreiRS Data 16 martie 2013 11:42:48
Problema Suma si numarul divizorilor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.81 kb
#include <fstream>
#include <algorithm>
#include <math.h>
#include <stdlib.h>
using namespace std;

const int dim = 1000030, mod = 9973;
long long N;
int T, NF, NR, SUM, ciur[dim];
struct fact { int p, n; } F[dim/10];

int putere (int baza, int exp)
{
	int x = 1, b;
	for (b = 20; b >= 0; b--)
	{
		x = (x * x) % mod;
		if ((exp >> b) & 1)
			x = (x * baza) % mod;
	}
	return x;
}

void euclid_extins (int a, int &x, int b, int &y, int &d)
{
	if (b == 0)
	{
		d = a;
		x = 1;
		y = 0;
		return;
	}
	int x0, y0;
	euclid_extins (b, x0, a % b, y0, d);
	
	x = y0;
	y = x0 - (a / b) * y0;
	if (y < 0) y += (-y / mod + 1) * mod;
	y %= mod;
	
	return;
}

void calc_ciur ()
{
	int i, j;
	for (i = 2; i < dim; i++)
	{
		if (ciur[i]) continue;
		ciur[++ciur[0]] = i;
		for (j = i << 1; j < dim; j += i)
			ciur[j] = 1;
	}
}

void calc_factori_primi ()
{
	int i, sq = sqrt (N);
	long long x = N, d;
	NF = -1;
	
	for (i = 1; ciur[i] <= sq; i++)
	{
		d = ciur[i];
		F[++NF].p = d % mod;
		F[NF].n = 0;
		for (; x % d == 0; x /= d)
			F[NF].n ++;
	}
	if (x != 1)
	{
		F[++NF].p = x % mod;
		F[NF].n = 1;
	}
}

void calc_nr_divizori ()
{
	NR = 1;
	for (int i = 0; i <= NF; i++)
		NR *= (F[i].n + 1);
}

void calc_suma_divizori ()
{
	SUM = 1;
	int a, b, x, y, d;
	for (int i = 0; i <= NF; i++)
	{
		a = putere (F[i].p, F[i].n + 1) - 1;
		if (a < 0) a += mod;
		
		b = F[i].p - 1;
		euclid_extins (b, x, mod, y, d);
		
		SUM = SUM * a % mod * x % mod;
	}
}

int main ()
{
	freopen ("ssnd.in", "r", stdin);
	freopen ("ssnd.out", "w", stdout);
	
	calc_ciur ();
	
	scanf ("%d", &T);
	while (T --)
	{
		scanf ("%lld", &N);
		
		calc_factori_primi ();
		calc_nr_divizori ();
		calc_suma_divizori ();
		
		printf ("%d %d\n", NR, SUM);
	}
	
	return 0;
}