Cod sursa(job #2759782)

Utilizator rusenmihai101@gmail.comMihai Rusen [email protected] Data 20 iunie 2021 14:49:14
Problema Suma si numarul divizorilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.83 kb
#include <fstream>
#include <algorithm>
#include <bitset>
#define mil 1000000
#define MOD 9973
using namespace std;
using ll = long long;
const string name("ssnd");
ifstream cin(name + ".in");
ofstream cout(name + ".out");

bitset<mil + 5> E;
unsigned int prime[80001], ind;

void ciur(){
    for(int i = 2; i * i <= mil; ++i)
        for(int j = 2; i * j <= mil; ++j)
            E[i * j] = 1;
    prime[++ind] = 2;
    for(int i = 3; i < mil; i += 2)
        if(!E[i])
            prime[++ind] = i;
}

void Euclid(ll nr, ll m, ll &x, ll &y){
    if(!m)
        x = 1, y = 1;
    else{
        ll x1, y1;
        Euclid(m, nr % m, x1, y1);
        x = y1;
        y = x1 - nr / m * y1;
    }
}

ll put(ll baza, ll putere){
    if(!putere)
        return 1;
    if(putere % 2)
        return put(baza, putere / 2) * put(baza, putere / 2) % MOD * baza % MOD;
    return put(baza, putere / 2) * put(baza, putere / 2) % MOD;
}

void rez(ll x){
    ll sum = 1, poz = 1, nrdiv = 1;
    while(x > 1){
        ll p = 0;
        while(x % prime[poz] == 0)
            x /= prime[poz], p++;
        if(p){
            ll numarator = (put(prime[poz], p + 1) - 1) % MOD;
            ll x, y;
            Euclid(prime[poz] - 1, MOD, x, y);
            while(x < 0)
                x += MOD;
            ll numitor = x;
            sum = sum * numarator % MOD * numitor % MOD;
            nrdiv *= (p + 1);
        }
        ++poz;
        if(x > 1 && 1LL * prime[poz] * prime[poz] > x)
            break;
    }
    if(x > 1){
        nrdiv *= 2;
        sum = 1LL * sum * (x + 1) % MOD;
    }

    cout << nrdiv << ' ' << sum % MOD << '\n';
}

int main(){

    ciur();
    int n;
    cin >> n;
    for(int i = 1; i <= n; ++i){
        ll x;
        cin >> x;
        rez(x);
    }

    return 0;
}