Cod sursa(job #3162528)

Utilizator fortyforBroscoi Mihai fortyfor Data 29 octombrie 2023 13:03:32
Problema Suma si numarul divizorilor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.4 kb
#include <iostream>
#include <fstream>
#include <cmath>
#define MOD 9973

/*Divizorii unui număr natural n reprezintă mulţimea de numere naturale, mai mici sau egale cu n,
cu proprietatea că divid pe n. Să se determine pentru t numere naturale cardinalul acestei mulţimi
şi restul împărţirii sumei elementelor mulţimii la 9973.*/

std::ifstream fin ("ssnd.in"); //input file
std::ofstream fout ("ssnd.out"); //output file
unsigned long long pr(long long a, long long b) { //functie de exponentiere
    long long thing = 1;
    while (b>0){
        if (b&1) {thing=thing*a;}
        a=a*a;
        b >>=1;
    }
    return thing;
}
void gSoE(bool* numlist, unsigned long long n=1) { //generate the Sieve of Erasthothenes on a boolean array of length n
    for (unsigned long long i=2;2*i<=n;i++)
    {
        numlist[2*i]=1;
    }
    for (unsigned long long i=3;i*i<=n;i+=2)
    {
        if (!numlist[i]) {
            for (unsigned long long j=(i<<1);j<=n;j+=i)
            {
                numlist[j]=1;
            }
        }
    }
}
unsigned short expo(long long a, long long p) { //gaseste puterea unui numar prim din descompunerea in factori (practic logaritm cu baza p de a)
    unsigned short c=0;
    while (a%p==0) {
        a/=p;c++;
    }
    return c;
}
    int main(){
    unsigned short t;
    fin >> t; //get number of iterations
    for (int i=0;i<t;i++)
    {
        unsigned long long n; //initialize current number
        fin >> n; //read current number from file
        bool primeList[n+1]{}; //Create empty boolean array of length n+1
        gSoE(primeList, n+1); //Imprint Sieve of Erasthothenes on said boolean array
        unsigned long long gamma=1,sigma=1; //initialize number of divisors and sum of divisors
        if (n%2==0) {gamma*=(expo(n, 2)+1);sigma*=(pr(2, expo(n, 2)+1)-1)%MOD; while(n%2){n/=2;} }
        for (unsigned long long j=3;j*j<=n;j+=2)
        {
            if (!primeList[j] && n%j==0) {
                gamma*=(expo(n, j)+1); //add divisors implied by prime factor
                sigma*=((pr(j, expo(n, j)+1)-1)/(j-1))%MOD; //sum (mod 9973) divisors implied by prime factor
                while (n%j){n/=j;} //remove prime factor from number
            }
        }
        if (!primeList[n]) {gamma*=2;sigma*=(n*n-1)/(n-1)%MOD;}
        fout << gamma << " " << sigma%MOD << std::endl; //write number of divisors and sum of divisors mod 9973 of currrent number
    }
    return 0;
}