Cod sursa(job #1953590)

Utilizator antanaAntonia Boca antana Data 4 aprilie 2017 21:42:47
Problema Suma si numarul divizorilor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.17 kb
#include <bits/stdc++.h>

#define MAXN 1000001
#define MOD 9973

using namespace std;

int primes[MAXN], K;
bool sieve[MAXN];

void sieveOfErathostenes() {
    int prime = 2;
    while(prime * prime < MAXN) {
        for(int i = prime; i*prime < MAXN; ++i)
            sieve[i * prime] = 1;
        prime++;
        while(sieve[prime])
            prime++;
    }
    for(int i=2; i<MAXN; ++i)
        if(!sieve[i])
            primes[K++] = i;
}

long long raiseToPower(long long f, int exp) {
    long long ans = 1;
    while(exp) {
        if(!(exp&1)) {
            exp /= 2;
            f = (f * f) % MOD;
        }else {
            exp--;
            ans = (ans * f) % MOD;
        }
    }
    return ans;
}

inline void primeFactors(int number, long long &dividers, long long &sum) {
    int power = 0;
    long long upper, lower;
    for(int i=0; i<K && primes[i] * primes[i] <= number; ++i) {
        if(number % primes[i] == 0) {
            power = 0;
            upper = 1;
            while(number % primes[i] == 0) {
                power++;
                number /= primes[i];
                upper = (upper * primes[i]) % MOD;
            }
            dividers = dividers * (power + 1);

            upper = (upper * primes[i]) % MOD;
            upper -= 1;
            if(upper < 0)
                upper += MOD;

            lower = raiseToPower(primes[i] - 1, MOD - 2);
            sum = (sum * upper) % MOD;
            sum = (sum * lower) % MOD;
        }
    }

    if(number > 1) {
        dividers *= 2;
        upper = (number * number) % MOD;
        upper -= 1;
        if(upper < 0)
            upper += MOD;

        lower = raiseToPower(number - 1, MOD - 2);
        sum = (sum * upper) % MOD;
        sum = (sum * lower) % MOD;
    }
}

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

    int n, t;
    long long dividers, sum;
    sieveOfErathostenes();

    scanf("%d", &t);
    while(t -- ) {
        scanf("%d", &n);
        dividers = sum = 1;
        primeFactors(n, dividers, sum);
        printf("%lld %lld\n", dividers, sum);
    }

    return 0;
}