Cod sursa(job #916294)

Utilizator AndreiRSStatescu Andrei Rares AndreiRS Data 16 martie 2013 12:01:26
Problema Suma si numarul divizorilor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.75 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];

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 + (-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_nr_divizori (int n)
{
	NR *= (n + 1);
}

void calc_suma_divizori (int p, int n)
{
	int a, b, x, y, d;

	a = putere (p, n + 1) - 1;
	if (a < 0) a += mod;
	
	b = p - 1;
	if (b < 0) b += mod; 
	euclid_extins (b, x, mod, y, d);
	
	SUM = SUM * a % mod * x % mod;
}


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

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