Cod sursa(job #2550242)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 18 februarie 2020 17:04:06
Problema Suma si numarul divizorilor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.98 kb
#include <fstream>
#include <vector>
#include <cstdio>

using namespace std;

ofstream fout("ssnd.out");

class InParser
{
private:
    FILE *fin;
    char *buff;
    int sp;

    char read_ch()
    {
        ++sp;
        if (sp == 4096)
        {
            sp = 0;
            fread(buff, 1, 4096, fin);
        }
        return buff[sp];
    }

public:
    InParser(const char* nume)
    {
        fin = fopen(nume, "r");
        buff = new char[4096]();
        sp = 4095;
    }

    InParser& operator >> (int &n)
    {
        char c;
        while (!isdigit(c = read_ch()) && c != '-');
        int sgn = 1;
        if (c == '-')
        {
            n = 0;
            sgn = -1;
        }
        else
        {
            n = c - '0';
        }
        while (isdigit(c = read_ch()))
        {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }

    InParser& operator >> (long long &n)
    {
        char c;
        n = 0;
        while (!isdigit(c = read_ch()) && c != '-');
        long long sgn = 1;
        if (c == '-')
        {
            n = 0;
            sgn = -1;
        }
        else
        {
            n = c - '0';
        }
        while (isdigit(c = read_ch()))
        {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }
};

InParser fin("ssnd.in");

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

long long N;

int d[SQRT + 5];

int nrp, primes[SQRT + 5];

int nrDiv, sumaDiv;

int LgPut(long long base, int exp)
{
    int ans = 1, aux = base % MOD;

    for(int i = 1; i <= exp; i <<= 1)
    {
        if(i & exp)
            ans = (ans * aux) % MOD;

        aux = (aux * aux) % MOD;
    }

    return ans;
}

void Erathostenes()
{
    for(int i = 3; i * i <= SQRT; i += 2)
        if(!d[i])
        {
            for(int j = i * i; j <= SQRT; j += 2 * i)
                d[j] = 1;
        }

    primes[++nrp] = 2;
    for(int i = 3; i <= SQRT; i += 2)
        if(!d[i])
            primes[++nrp] = i;
}

void Push(long long div, int exp)
{
    nrDiv *= (exp + 1);

    int numarator = LgPut(div, exp + 1) - 1;
    if(numarator < 0)
        numarator += MOD;

    int numitor = LgPut(div - 1, MOD - 2);

    sumaDiv = (1LL * sumaDiv * numarator * numitor) % MOD;
}

void Solve()
{
    nrDiv = 1;
    sumaDiv = 1;

    fin >> N;

    for(int i = 1; i <= nrp; i++)
        if(1LL * primes[i] * primes[i] > N)
            break;
        else
        {
            int div = 1LL * primes[i];
            int exp = 0;

            while(N % div == 0)
            {
                N /= div;
                exp++;
            }

            Push(div, exp);
        }

    if(N != 1)
        Push(N, 1);

    fout << nrDiv << ' ' << sumaDiv << '\n';
}

int main()
{
    Erathostenes();

    int t;
    fin >> t;

    while(t--)
        Solve();

    return 0;
}