Cod sursa(job #2823634)

Utilizator tiut_cristianTiut Cristian tiut_cristian Data 29 decembrie 2021 09:40:54
Problema Suma si numarul divizorilor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.23 kb
#include <fstream>

using namespace std;

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

int k, prime[1000001];
int t, mod = 9973;

void generareCiur(int & k, int prime[])
{
    bool vf[1000001]={0};
    prime[1] = 2;
    k = 1;
    for(int i = 3; i <= 1000001; i+=2)
        vf[i] = 1;
    for(int i = 3; i <= 1000001; i+=2)
        if(vf[i])
        {
            prime[++k] = i;
            for(int j = 2*i; j <= 1000001; j += i)
                vf[j] = 0;
        }
}

int putere(int baza, int exp)
{
    baza %= mod;
    if(exp == 1)
        return baza;
    if(exp%2 == 1)
        return baza*putere(baza*baza%mod, exp/2)%mod;
    return putere(baza*baza%mod, exp/2)%mod;
}

void Euclid(int a, int b, long long & x, long long & y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
    }
    else
    {
        long long x1, y1;
        Euclid(b, a % b, x1, y1);
        x = y1;
        y = x1 - y1 * (a / b);
    }
}

int invMod(int nr)
{
    long long x, y;
    Euclid(nr, mod, x, y);
    if(x<0)
        x += mod*(-x/mod+1);
    return x%mod;
}

void descompunereInFactori(int k, long long nr, long long & nrDiv, long long & sumDiv, int prime[])
{
    nrDiv = sumDiv = 1;
    long long aux = nr;
    int i = 1;
    while(nr > 1 && i<=k && prime[i]*prime[i]<=aux)
    {
        int p = 0;
        int put = 1;
        while(nr%prime[i] == 0)
        {
            //fout << prime[i] << ' ';
            nr /= prime[i];
            //put *= prime[i];
            //put %= mod;
            //fout << put << '\n';
            p++;
        }
        if(p)
        {
            nrDiv *= (p+1);
            put = putere(prime[i], p+1);
            sumDiv = (sumDiv * ((put+mod-1)%mod * invMod(prime[i]-1)) )%mod;
        }
        i++;
    }
    if(nr > 1)
    {
        //fout << "ok";
        nrDiv *= 2;
        sumDiv = (sumDiv*((nr*nr%mod+mod-1)%mod*invMod(nr-1))) % mod;
    }
}

int main()
{
    generareCiur(k, prime);
    fin >> t;
    for(int i = 1; i <= t; i++)
    {
        long long nr, sumDiv, nrDiv;
        fin >> nr;
        descompunereInFactori(k, nr, nrDiv, sumDiv, prime);
        fout << nrDiv << ' ' << sumDiv << '\n';
    }
    return 0;
}