Cod sursa(job #2823637)

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

using namespace std;

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

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

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 precalculare_invMod(int v[])
{
    for(int i = 1; i <= 9973; i++)
        v[i] = invMod(i);
}

void descompunereInFactori(int k, long long nr, long long & nrDiv, long long & sumDiv, int prime[])
{
    nrDiv = sumDiv = 1;
    int i = 1;
    while(nr > 1 && i<=k && prime[i]*prime[i]<=nr)
    {
        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);
            nrDiv %= mod;
            sumDiv = (sumDiv * ((put*prime[i]%mod + mod - 1)%mod * v[(prime[i]-1)%mod]) )%mod;
        }
        i++;
    }
    if(nr > 1)
    {
        //fout << "ok";
        nrDiv *= 2;
        nrDiv %= mod;
        sumDiv = (sumDiv*((nr%mod*(nr%mod)%mod+mod-1)%mod*v[(nr-1)%mod])) % mod;
    }
}

int main()
{
    generareCiur(k, prime);
    precalculare_invMod(v);
    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;
}