Cod sursa(job #2610192)

Utilizator dancu_mihai13Dancu Mihai dancu_mihai13 Data 4 mai 2020 16:56:13
Problema Suma si numarul divizorilor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.79 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 1000000;
const int MOD = 9973;
int primes[NMAX], c;
bool ciur[NMAX / 2];

void init()
{
    primes[0] = 2;
    for(int i = 1; i * i < NMAX; i++)
        if(!ciur[i])
        {
            primes[++c] = 2 * i + 1;
            for(int j = 3 * i + 1; j < NMAX; j += (2 * i + 1))
                ciur[j] = 1;
        }
    for(int i = sqrt(NMAX); i < NMAX; i++)
        if(!ciur[(i - 1) / 2] && i % 2 == 1)
            primes[++c] = i;
}

int exp_log(int n, int p)
{
    int r = 1;
    while(p)
    {
        if(p % 2)
            r = r * n;
        n = n * n;
        p /= 2;
    }
    return r;
}

void divizori(long long numar)
{
    int sum = 1, nr_div = 1;
    if(numar < NMAX && !ciur[(numar - 1) / 2] && (numar % 2 == 1 || numar == 2))
    {
        nr_div = 2;
        sum = (numar + 1) % MOD;
    }
    else
    {
        int i = 0;
        int d = primes[i];
        int p = 0;
        while(!(numar % d))
        {
            numar /= d;
            p++;
        }
        nr_div *= (p + 1);
        sum *= ((pow(d, p + 1) - 1) / (d - 1));

        while(numar > 1)
        {
            p = 0; i++;
            d = primes[i];
            if(d * d > numar)
                d = numar;
            while(!(numar % d))
            {
                numar /= d;
                p++;
            }
            nr_div *= (p + 1);
            sum = ((sum * (exp_log(d, p + 1) - 1)) / (d - 1)) % MOD;
        }
    }
    fout << nr_div << ' ' << sum << '\n';
}

int main()
{
    int nr; long long val; fin >> nr;
    init();
    for(int i = 0; i < nr; i++)
    {
        fin >> val;
        divizori(val);
    }
    return 0;
}