Cod sursa(job #1736712)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 2 august 2016 14:56:35
Problema Suma si numarul divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.93 kb
#include <bits/stdc++.h>

using namespace std;

constexpr int MAX_N = 1000000;

bitset<MAX_N + 1> sieve;
vector<int> primes;

void genSieve()
{
    for (int i = 4; i <= MAX_N; i += 2)
        sieve[i] = true;

    for (int i = 2; i <= MAX_N; i++)
        if (sieve[i] == false)
        {
            primes.push_back(i);

            if (1LL * i * i > MAX_N)
                continue;

            for (int j = i * i; j <= MAX_N; j += i)
                sieve[j] = true;
        }
}

long long power(long long n, long long p, int MOD)
{
    long long solution = 1;

    while (p)
    {
        if (p & 1)
            solution = solution * n % MOD;

        n = n * n % MOD;
        p >>= 1;
    }

    return solution;
}

long long inverse(long long n, int MOD)
{
    return power(n, MOD - 2, MOD);
}

pair<long long,long long> compute(long long n, int MOD)
{
    long long ndiv = 1;
    long long sum = 1;

    int i = 0;

    while (i < primes.size() && 1LL * primes[i] * primes[i] <= n)
    {
        int &p = primes[i++];

        if (n % p == 0)
        {
            long long e = 0;

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

            ndiv = ndiv * (e + 1) % MOD;

            long long term = power(p, e + 1, MOD);
            term = (term - 1 + MOD) % MOD;
            term = term * inverse(p - 1, MOD) % MOD;

            sum = sum * term % MOD;
        }
    }

    if (n > 1)
    {
        ndiv = ndiv * 2 % MOD;

        long long term = power(n, 2, MOD);
        term = (term - 1 + MOD) % MOD;
        term = term * inverse(n - 1, MOD) % MOD;

        sum = sum * term % MOD;
    }

    return {ndiv, sum};
}

int main()
{
    ifstream in("ssnd.in");
    ofstream out("ssnd.out");

    genSieve();

    int T;
    in >> T;

    while (T--)
    {
        long long n;
        in >> n;

        auto p = compute(n, 9973);
        out << p.first << " " << p.second << endl;
    }

    return 0;
}