Cod sursa(job #649460)

Utilizator mihaibogdan10Mihai Bogdan mihaibogdan10 Data 16 decembrie 2011 09:15:39
Problema Suma si numarul divizorilor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include<cstdio>
#include<cmath>
#include<vector>
#define MOD 9973
using namespace std;

vector <bool> ePrim;
vector <int> nrPrime;

//ridicare la putere in timp logaritmic
int Pow(int baza, int exp){
	if (exp == 0) return 1;
	if (exp == 1) return baza;
	if (exp % 2 == 1) return Pow(baza, exp - 1) * baza;
	int x = Pow (baza, exp / 2);
	return x * x;
}

void DetNumerelePrime(){
	//determin numerele prime pana la 1.000.000 folosind ciurul lui Eratostene
	
	int i, j, n = 1000000;
	ePrim.assign(n + 1, 1);
	int radPatrata = (int)sqrt(n);
	for (i = 2; i <= radPatrata; i++)
			for (j = i * 2; j <= n; j += i) ePrim[j] = 0;
	
	for (i = 2; i <= n; i++)
		if (ePrim[i]) nrPrime.push_back(i);
	ePrim.clear();
}

int main(){
	freopen ("ssnd.in", "r", stdin), freopen("ssnd.out", "w", stdout);
	DetNumerelePrime();
	int i, j, n, x, nrDiv, sumaDiv, exp, div, radPatrata;
	scanf("%d", &n);
	
	for (i = 0; i < n; i++){
		scanf("%d", &x);
		nrDiv = 1, sumaDiv = 1, j = 0, div = nrPrime[j], radPatrata = (int)sqrt(x);;
		
		//descompun fiecare numar in factori primi
		while (x != 1 && div <= radPatrata){
			exp = 0;
			if (x % div == 0){
				while (x % div == 0){
					x /= div;
					exp++;
				}
				sumaDiv = (sumaDiv * (Pow(div, exp + 1) - 1) / (div - 1)) % MOD;
				nrDiv *= exp + 1;
				radPatrata = (int)sqrt(x);
			}
			div = nrPrime[++j];
		}
		
		//daca x != 1 la iesire atunci el e un numar prim
		if (x != 1) nrDiv *= 2, sumaDiv = (sumaDiv * (x + 1)) % MOD;
		printf("%d %d\n", nrDiv, sumaDiv);
	}
	
	return 0;
}