Cod sursa(job #3130118)

Utilizator prares06Papacioc Rares-Ioan prares06 Data 16 mai 2023 21:27:46
Problema Suma si numarul divizorilor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include<fstream>
#include<vector>
#include<unordered_map>

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

#define MIL 1000001
#define MOD 9973

std::unordered_map<unsigned, unsigned short> um;
std::vector<unsigned>::iterator IT;
std::vector<unsigned> prime;
int t, n, count, numitor, numarator;

int Putere(int A , int n)
{
    if(n == 0)
        return 1;
    if(n % 2 == 1)
        return A * Putere(A , n - 1) % MOD;
    int P = Putere(A , n / 2) % MOD;
    return P * P % MOD;
}

void init_sieve(){
    std::vector<bool> ciur(MIL, false);

    ciur[0] = ciur[1] = true;
    
    for(int i = 2; i * i <= MIL; ++i)
        if(!ciur[i])
            for(int j = i; j * i <= MIL; ++j)
                ciur[i * j] = true;


    for(int i = 2; i <= MIL; ++i)
        if(!ciur[i])
            prime.push_back(i);


    ciur.~vector();
}

int modInverse(int A, int M)
{
    int m0 = M;
    int y = 0, x = 1;
 
    if (M == 1)
        return 0;
 
    while (A > 1) {
        // q is quotient
        int q = A / M;
        int t = M;
 
        // m is remainder now, process same as
        // Euclid's algo
        M = A % M, A = t;
        t = y;
 
        // Update y and x
        y = x - q * y;
        x = t;
    }
 
    // Make x positive
    if (x < 0)
        x += m0;
 
    return x;
}

int main(){
    fin >> t;
    
    init_sieve();
    
    while(t--){
        fin >> n;
        
        IT = prime.begin();
        
        count = numitor = numarator = 1;
        
        while(IT != prime.end() && (*IT) <= n && n != 1){
            while(n % (*IT) == 0){
                if(um.find(*IT) != um.end())
                    ++um[*IT];
                else
                    um[*IT] = 1;
                n /= *IT;
            }
            
            ++IT;
        }
        
        for(auto elem : um){
            count = count * (elem.second + 1);
            numarator = (numarator * (Putere(elem.first, elem.second + 1) - 1)) % MOD;
            numitor = (numitor * (elem.first - 1)) % MOD;
        }
        
        um.clear();
        
        fout << count << " " << (numarator * modInverse(numitor, MOD)) % MOD << std::endl;
    }
}