Pagini recente » Cod sursa (job #3324772) | Cod sursa (job #2818376) | Cod sursa (job #1845000) | Cod sursa (job #2013072) | Cod sursa (job #3329791)
#include <iostream>
#include <vector>
#include <fstream>
#include <cmath>
using namespace std;
int LIMIT = 1000000;
long long MOD = 9973;
vector<int> primes; // lista numerelor prime
vector<bool> marked; // marcare pentru ciur
// lista de prime pana la LIMIT folosind ciurul lui eratostene
void generatePrimes() {
/// true = neprim, false = prim
marked.assign(LIMIT + 1, false);
marked[0] = marked[1] = true;
// elimin multiplii lui 2
for (int i = 4; i <= LIMIT; i += 2)
marked[i] = true;
for (int i = 3; 1LL * i * i <= LIMIT; i += 2)
if (!marked[i])
for (int j = i * i; j <= LIMIT; j += 2 * i)
marked[j] = true;
// adaug numerele prime in lista
primes.push_back(2);
for (int i = 3; i <= LIMIT; i += 2)
if (!marked[i])
primes.push_back(i);
}
// calculez numarul si suma divizorilor pentru n
void computeDivisors(long long n, long long &countDiv, long long &sumDiv) {
countDiv = 1; // numarul divizorilor
sumDiv = 1; // suma divizorilor
for (int p : primes) {
if (1LL * p * p > n)
break; // daca p^2 > n, n ramane prim sau 1
if (n % p == 0) {
long long pPower = 1;
int exp = 0;
// calculam puterea lui p si exponentul in factorizarea lui n
while (n % p == 0) {
n /= p;
pPower *= p;
exp++;
}
// actualizam numarul de divizori
countDiv *= (exp + 1);
// actualizam suma divizorilor modulo MOD
sumDiv = (sumDiv * ((pPower * p - 1) / (p - 1) % MOD)) % MOD;
}
}
// daca ramane un numar prim mai mare decat sqrt(n)
if (n > 1) {
countDiv *= 2; // are exact doi divizori: 1 si n
sumDiv = (sumDiv * ((n * n - 1) / (n - 1) % MOD)) % MOD;
}
}
int main() {
ifstream fin("ssnd.in");
ofstream fout("ssnd.out");
generatePrimes();
int t;
fin >> t; // numarul de teste
while (t--) {
long long n, divCount, divSum;
fin >> n;
computeDivisors(n, divCount, divSum);
fout << divCount << " " << divSum << "\n";
}
return 0;
}