Cod sursa(job #3178506)

Utilizator rapidu36Victor Manz rapidu36 Data 1 decembrie 2023 20:04:29
Problema Suma si numarul divizorilor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
#include <fstream>
#include <vector>
#include <bitset>

using namespace std;

const int MOD = 9973;
const int RAD_VMAX = 1e6;

vector <int> prime;
vector <int> inv(MOD, 0);

void calcul_prime()
{
    bitset <RAD_VMAX + 1> c;
    for (int i = 2; i * i <= RAD_VMAX; i++)
    {
        if (!c[i])
        {
            for (int multiplu = i * i; multiplu <= RAD_VMAX; multiplu += i)
            {
                c[multiplu] = 1;
            }
        }
    }
    for (int i = 2; i <= RAD_VMAX; i++)
    {
        if (!c[i])
        {
            prime.push_back(i);
        }
    }
}

int putere(int a, int n)
{
    ///calculeaza a la n % MOD
    int p = 1;
    while (n != 0)
    {
        if (n % 2 != 0)
        {
            p = p * a % MOD;
        }
        a = a * a % MOD;
        n /= 2;
    }
    return p;
}

int inversul(int a)
{
    return putere(a, MOD - 2);
}

void calcul_invers()
{
    for (int i = 1; i < MOD; i++)
    {
        if (inv[i] == 0)
        {
            inv[i] = inversul(i);
            inv[inv[i]] = i;
        }
    }
}

void calcul_sum_nr_div(long long n, long long &nrd, long long &sumd)
{
    unsigned int i = 0;
    nrd = sumd = 1;
    while (i < prime.size() && (long long)prime[i] * prime[i] <= n)
    {
        if (n % prime[i] == 0)
        {
            int p = 0;
            while (n % prime[i] == 0)
            {
                p++;
                n /= prime[i];
            }
            p++;
            nrd = (nrd * p) % MOD;
            sumd = putere(prime[i] % MOD, p);
            if (sumd == 0)
            {
                sumd = MOD - 1;
            }
            else
            {
                sumd -= 1;
            }
            sumd = sumd * inv[(prime[i] - 1 + MOD) % MOD] % MOD;
        }
        i++;
    }
    if (n != 1)
    {
        nrd = nrd * 2 % MOD;
        sumd = sumd * (n + 1) % MOD;
    }
}

int main()
{
    ifstream in("ssnd.in");
    ofstream out("ssnd.out");
    calcul_prime();
    calcul_invers();
    int t;
    in >> t;
    for (int i = 0; i < t; i++)
    {
        long long n, nrd, sumd;
        in >> n;
        calcul_sum_nr_div(n, nrd, sumd);
        out << nrd << " " << sumd << "\n";
    }
    in.close();
    out.close();
    return 0;
}