Cod sursa(job #2627284)

Utilizator RobertLearnsCDragomir Robert. RobertLearnsC Data 10 iunie 2020 12:38:26
Problema Suma si numarul divizorilor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.78 kb
#include <bits/stdc++.h>
#define modulo 9973
using namespace std;

int t;
long long nr;
vector <int> primeNumbers;
bitset <1000005> isPrime;

long long lgpow(long long base, int exp) {
    int r = 1;
    while(exp) {
        if(exp % 2) {
            r = (1LL * r * base) % modulo;
        }
        base = (1LL * base * base) % modulo;
        exp /= 2;
    }
    return r;
}

long long invers(long long inv) {
    return lgpow(inv, modulo - 2);
}

void generatePrimeNumbers() {
    isPrime[0] = isPrime[1] = 1;
    for(int i = 2; i <= 1000003; i++) {
        if(!isPrime[i]) {
            primeNumbers.push_back(i);
            for (int j = i * 2; j <= 1000003; j += i) {
                isPrime[j] = 1;
            }
        }
    }
}

void update(long long &sum, long long &nrDiv,  long long nr, int exp) {
    sum = sum * ((lgpow(nr, exp + 1) - 1) * invers(nr - 1)) % modulo;
    nrDiv = nrDiv * (exp + 1);
}

int descomp(long long &nr, int div) {
    int exp = 0;
    while(nr % div == 0) {
        nr /= div;
        exp++;
    }
    return exp;
}

void solve() {
    long long sum = 1, nrDiv = 1;
    for(int i = 0; nr > 1 && i < primeNumbers.size() && primeNumbers[i] * primeNumbers[i] <= nr; i++) {
        if(nr % primeNumbers[i]) continue;

        int exp = descomp(nr, primeNumbers[i]);
        update(sum, nrDiv, primeNumbers[i], exp); /// actualizam suma si numarul de divizori
    }
    if(nr > 1) {
        update(sum, nrDiv, nr, 1); /// actualizam suma si numarul de divizori
    }
    printf("%d %lld\n", nrDiv, sum);
}

int main() {
    freopen("ssnd.in", "r", stdin);
    freopen("ssnd.out", "w", stdout);
    generatePrimeNumbers();

    scanf("%d", &t);
    while(t--) {
        scanf("%lld", &nr);
        solve();
    }
}