Cod sursa(job #1231386)

Utilizator daniel.amarieiDaniel Amariei daniel.amariei Data 20 septembrie 2014 14:05:04
Problema Suma si numarul divizorilor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.6 kb
#include <fstream>
#include <bitset>
#include <cmath>
#include <list>

#define M 9973
#define SIZE 1000001

using namespace std;


list<int> P;
bitset<SIZE> S;

void sieve()
{
	for (int i = 2; i * i < SIZE; ++i)
	{
		if (!S.test(i))
		{
			for (int j = i+i; j < SIZE; j += i)
			{
				S.set(j);
			}
		}
	}
	
	for (int i = 2; i < SIZE; ++i) 
	{
		if (!S.test(i))
		{
			P.push_back(i);
		}
	}
}

int factors(long long & n, long long p) 
{
	int d = 0;
	while (n > 1 && ((n % p) == 0))
	{
		++d;
		n /= p;
	}
	
	return d;
}

long long pow(long long x, long long n)
{
	if (n == 0) return 1L;
	if (n == 1) return x;
	
	if ((n % 2) == 0) return pow(x*x, n/2);
	else return x * pow(x*x, n/2);
}

int main()
{
	ifstream ifs("ssnd.in");
	ofstream ofs("ssnd.out");
	
	sieve();
	
	int t;
	ifs >> t;
	
	for (int i = 0; i < t; ++i) 
	{
		long long n;
		ifs >> n;

		long long sqrt_n = sqrt(n);
		
		long long card = 1;
		long long sum = 1;
	
		for (list<int>::iterator it = P.begin(); it != P.end() && (*it <= sqrt_n); ++it) 
		{
			long long p = *it;
			long long d = factors(n, p);
				
			if (d > 0)
			{
				// Update the number of divisors
				card *= (d + 1);
					
				// Update the sum
				long long f = ( (pow(p, d + 1) - 1) / (p - 1) ) % M;
				sum = sum * f % M; 
			}
		}
		
		if (n > 1)
		{
			long long d = 1;
			// Update the number of divisors
			card *= (d + 1);
				
			// Update the sum
			long long f = ( (pow(n, d + 1) - 1) / (n - 1) ) % M;
			sum = sum * f % M; 
		}
		
		ofs << card << " " << sum << "\n";
	}
	
	return 0;
}