Cod sursa(job #3148330)

Utilizator andreiomd1Onut Andrei andreiomd1 Data 31 august 2023 05:10:46
Problema Suma si numarul divizorilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.14 kb
#include <fstream>
#include <vector>

using namespace std;
using ll = long long;

ifstream f("ssnd.in");
ofstream g("ssnd.out");

static constexpr int VMAX = ((int)(1e6) + 1);
static constexpr int nrMAX = ((int)(8e4) + 1);
static const int MOD = 9973;

vector<ll> V;

bool sel[VMAX];
int primes[nrMAX];

static inline ll my_max(const ll &a, const ll &b)
{
    return ((a > b) ? a : b);
}

static inline ll read()
{
    f.tie(nullptr);

    int t = 0;
    f >> t;

    ll Max = 0;

    for (int i = 1; i <= t; ++i)
    {
        ll x = 0;
        f >> x;

        V.push_back(x);

        Max = my_max(Max, x);
    }

    return Max;
}

static inline int my_sqrt(const ll &n)
{
    int l = 1, r = (int)(1e6), pos = 1;

    while (l <= r)
    {
        int mid = ((l + r) >> 1);

        if (1LL * mid * mid <= n)
            pos = mid, l = (mid + 1);
        else
            r = (mid - 1);
    }

    return pos;
}

static inline void sieve(const int &n)
{
    for (int i = 3; i * i <= n; i += 2)
        if (!sel[i])
            for (int j = i; j * i <= n; j += 2)
                sel[i * j] = 1;

    primes[++primes[0]] = 2;

    for (int i = 3; i <= n; i += 2)
        if (!sel[i])
            primes[++primes[0]] = i;

    return;
}

static inline pair<ll, ll> solve(ll &x)
{
    ll cnt = 1, sum = 1;

    int d = 2;
    int j = 1;

    while (j <= primes[0] && 1LL * d * d <= x && x != 1LL)
    {
        if (x % (1LL * d) == 0)
        {
            int p = 0;
            ll fact = 1;

            while (x % (1LL * d) == 0)
                ++p, x /= (1LL * d), fact *= (1LL * d);

            cnt *= 1LL * (p + 1);

            fact *= (1LL * d);
            --fact;
            fact /= (1LL * d - 1);

            fact %= (1LL * MOD);

            sum *= fact, sum %= (1LL * MOD);
        }

        d = primes[++j];
    }

    if (x != 1LL)
        cnt <<= 1LL, sum *= 1LL * ((1LL * x * x - 1LL) / (1LL * x - 1LL)) % (1LL * MOD);

    sum %= (1LL * MOD);

    return {cnt, sum};
}

int main()
{
    ll Max = read();

    sieve(my_sqrt(Max));

    for (auto it : V)
    {
        pair<ll, ll> x = solve(it);

        g << x.first << ' ' << x.second << '\n';
    }

    return 0;
}