Cod sursa(job #3297963)

Utilizator calinarulMarinescu Calin calinarul Data 24 mai 2025 23:02:11
Problema Suma si numarul divizorilor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.52 kb
#include <fstream>
#include <vector>
#include <bitset>
#define pb push_back
#define endl '\n'
#define int long long
using namespace std;

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

const int NMAX = 1e6 + 5;
const int MOD = 9973;
vector<int> primes;
bitset<NMAX> ciur;
int mx = 0;

int ridicare(int a, int b)
{
    int p = 1;
    a %= MOD;
    while (b)
    {
        if (b & 1) p = (p * a) % MOD;
        a = (a * a) % MOD;
        b >>= 1;
    }
    return p;
}

void eratostene()
{
    primes.pb(2);
    ciur[0] = 1;
    ciur[1] = 1;

    for (int i = 4; i < NMAX; i += 2)
        ciur[i] = 1;

    for (int i = 3; i * i < NMAX; i += 2)
    {
        if (!ciur[i])
        {
            for (int j = i * i; j < NMAX; j += i * 2)
                ciur[j] = 1;
        }
    }

    for (int i = 3; i < NMAX; i += 2)
    {
        if (!ciur[i])
            primes.pb(i);
    }
    mx = primes.size();
}

signed main()
{
    eratostene();
    int t; fin >> t;

    while (t--)
    {
        int n; fin >> n;
        int n_vechi = n;
        int cnt = 0;
        int d = 1;
        int s = 1;

        if (!ciur[n]) // prime
        {
            fout << "2 " << (n + 1) % MOD << endl;
            continue;
        }

        while (n > 1 && cnt < mx)
        {
            int p = primes[cnt];
            int cati = 0;

            if (n % p == 0)
            {
                while (n % p == 0)
                {
                    cati++;
                    n /= p;
                }
                cati++;

                d = (d * cati) % MOD;

                int part = (ridicare(p, cati) - 1 + MOD) % MOD;
                int inv = ridicare(p - 1, MOD - 2);
                int val = (part * inv) % MOD;

                s = (s * val) % MOD;
            }

            // Check next prime boundary and overflow possibility
            if (cnt + 1 >= mx || (primes[cnt + 1] * primes[cnt + 1] > n))
            {
                if (n > 1)
                {
                    cati = 2;
                    p = n;
                    d = (d * cati) % MOD;

                    int part = (ridicare(p, cati) - 1 + MOD) % MOD;
                    int inv = ridicare(p - 1, MOD - 2);
                    int val = (part * inv) % MOD;

                    s = (s * val) % MOD;
                    n = 1;
                }
                break;
            }
            cnt++;
        }

        if (n > 1 && n_vechi == n)
        {
            fout << "2 " << (n + 1) % MOD << endl;
            continue;
        }
        fout << d << " " << s << endl;
    }
}