Cod sursa(job #3329791)

Utilizator StefanStratonStefan StefanStraton Data 15 decembrie 2025 18:46:31
Problema Suma si numarul divizorilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.29 kb
#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;
}