Cod sursa(job #2900912)

Utilizator a.stanciuStanciu Adrian a.stanciu Data 12 mai 2022 14:50:18
Problema Suma si numarul divizorilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.02 kb
#include <bits/stdc++.h>

using namespace std;

auto primes_until(long limit)
{
    vector<bool> is_prime(limit + 1, true);
    is_prime[0] = false;
    is_prime[1] = false;

    vector<int> primes;

    for (auto i = 0l; i <= limit; ++i)
        if (is_prime[i]) {
            primes.push_back(i);

            for (auto j = i * i; j <= limit; j += i)
                is_prime[j] = false;
        }

    return primes;
}

auto solve(const vector<int>& primes, long x)
{
    const auto Mod = 9973;

    auto exp = [] (int a, int b) {
        if (b == 0)
            return 1;
        if (a == 0)
            return 0;

        int res = 1;

        while (b) {
            if (b & 0x1) {
                res = (1l * res * a) % Mod;
                --b;
            }

            a = (1l * a * a) % Mod;
            b /= 2;
        }

        return res;
    };

    auto inv = [&] (int x) {
        return exp(x, Mod - 2);
    };

    auto num_div = 1l;
    auto sum_div = 1l;

    for (auto p : primes) {
        if (1l * p * p > x) {
            // x is a prime > 1e6
            num_div *= 2;
            sum_div *= 1l * ((exp(x, 2) - 1 + Mod) % Mod) * inv(x - 1) % Mod;
            sum_div %= Mod;
            break;
        }

        auto cnt = 0;
        while (x % p == 0) {
            x /= p;
            ++cnt;
        }
        if (cnt == 0)
            continue;

        num_div *= (cnt + 1);
        sum_div *= 1l * ((exp(p, cnt + 1) - 1 + Mod) % Mod) * inv(p - 1) % Mod;
        sum_div %= Mod;

        if (x == 1)
            break;
    }

    return make_pair(num_div, sum_div);
}

int main()
{
    auto primes = primes_until(1e6);

    FILE *in = fopen("ssnd.in", "r");
    FILE *out = fopen("ssnd.out", "w");
    if (!in || !out)
        return -1;

    int nt;
    fscanf(in, "%d", &nt);

    while (nt--) {
        long x;
        fscanf(in, "%ld", &x);

        long num_div, sum_div;
        tie(num_div, sum_div) = solve(primes, x);

        fprintf(out, "%ld %ld\n", num_div, sum_div);
    }

    fclose(in);
    fclose(out);

    return 0;
}