Cod sursa(job #1599063)

Utilizator TeodorCotetCotet Teodor TeodorCotet Data 13 februarie 2016 16:19:32
Problema Suma si numarul divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.76 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

ifstream fin("ssnd.in");
ofstream fout("ssnd.out");

const int MOD = 9973;
const int MAXVAL = 1000000;

int n;

vector<int> v;
unsigned int check[(MAXVAL + 1) / 32 + 1];

bool getElement(unsigned int check[], int index) {

	index--; //nu exista indexul = 0
	int pos = index & 31;
	index = index >> 5;

	return check[index] & (1 << pos);
}

void setElement(unsigned int check[], int index) {

	index--;
	unsigned int pos = index & 31;
	index = index >> 5;

	check[index] |= (1 << pos);
}

void eratostene(int x) {

	for(int i = 2; i * i <= x; ++i) {
		if(getElement(check, i) == 0)
			for(int j = i * i; j <= x; j += i)
				setElement(check, j);
	}

	for(int i = 2; i <= x ; ++i)
		if(getElement(check, i) == 0)
			v.push_back(i);

}

void find(long long x) {

	int sumdiv = 1;
	int nrdiv = 1;

	for(unsigned i = 0 ; i < v.size(); ++i) {

		int d = v[i];

		if(1ll * d * d > x) break;
		if(x % d) continue;

		int nrd = 0;
		int sirSum = 1;
		int divPow = 1;

		while(x % d == 0) {

			divPow = (1ll * divPow * d) % MOD;
			sirSum = (1ll * sirSum + divPow) % MOD;

			x /= d;
			nrd++;
		}

		nrdiv = (1ll * nrdiv * (nrd + 1)) % MOD;
		sumdiv = (1ll * sumdiv * sirSum) % MOD;
	}

	if(x > 1) {
		/*
		 * poate sa ramana maxim un divizor neluat in calcul
		 * si anume cel mai mare, ca un divizor sa nu fie luat in calcul trebuie ca
		 * el sa fie mai mare decat produsul tutoro celoralati divizori(d^2 > x)
		 * nu poate fi adevarat decat pentru cel mai mare divizor prim
		 */
		nrdiv = (1ll * nrdiv * 2) % MOD;
		sumdiv = (1ll * sumdiv * (1 + x)) % MOD;
	}

	fout << nrdiv << " " << sumdiv << '\n';
}

int main() {

	fin >> n;

	eratostene(MAXVAL);

	while(n--) {

		long long x;
		fin >> x;
		find(x);
	}

	return 0;
}