Cod sursa(job #2277048)

Utilizator cristii2000cristiiPanaite Cristian cristii2000cristii Data 5 noiembrie 2018 19:10:14
Problema Suma si numarul divizorilor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.23 kb
#include <iostream>
#include <fstream>

using namespace std;

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

const int MOD = 9973;
const int N = 1000005;

bool ciur[N];

void eratostene(){
    for(int d = 2; d <= N; d++){
        if(!ciur[d])
            for(long long i = 2 * d; i <= N; i += d)
                ciur[i] = 1;
    }
}

pair <long long, long long> euclid(long long x, long long y){

    if(y == 0)
        return {1, 0};

    auto p = euclid(y, x % y);

    return {p.second, p.first - (x / y) * p.second};

}

long long inverModular(long long x){

    auto rez = euclid(x, MOD);

    return rez.first;
}

long long t;

long long putere(long long x, long long y){
    long long rez = 1;

    while (y){
        if(y & 1){
            rez = (1LL * rez *x) % MOD;
        }
        x = (1LL * x * x) % MOD;
        y >>= 1;
    }
    return rez;
}
long long suma = 1;
long long nrDiv = 1;

void Suma_nrDiv(long long x){
    long long p = 0;


    while(x % 2 == 0){
        x/=2;
        p++;
    }
    if(p != 0){
        nrDiv *= (p + 1);
        suma = (suma * (((putere(2, p + 1) - 1) * inverModular(1)) % MOD)) % MOD;
        p = 0;
    }

    for(long long d = 3; d * d < x; d += 2){
        if(ciur[d] == 0)
        if(x % d == 0){
            while (x % d == 0){
                x/=d;
                p++;
            }
            nrDiv *= (p + 1);
            long long inv = inverModular(d - 1);
            while (inv < 0)
                inv += MOD;
            long long put = putere(d, p + 1);
            if (inv != 0)
                suma = (suma * (((put - 1) * inv) % MOD)) % MOD;
            else
                suma = (suma * (p + 1)) % MOD;
        }
    }
    if(x > 1){
        nrDiv *= 2;
        long long inv = inverModular(x - 1);
        while (inv < 0)
            inv += MOD;
        long long put = putere(x, 2);
        if (inv != 0)
            suma = (suma * (((put - 1) * inv) % MOD)) % MOD;
        else
            suma = suma * 2 % MOD;
    }
}


int main() {

    ios::sync_with_stdio(false);

    eratostene();

    in >> t;

    for(long long i = 0; i < t; i++){
        suma = 1;
        nrDiv = 1;
        long long n;
        in >> n;
        Suma_nrDiv(n);

        out << nrDiv << " " << suma << "\n";
    }
    return 0;
}