Cod sursa(job #2217586)

Utilizator 1475369147896537415369Andrei Udriste 1475369147896537415369 Data 30 iunie 2018 23:57:13
Problema Suma si numarul divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.41 kb
#include <cstdio>
#include <iostream>
#include <string.h>
using namespace std;
#define MOD 9973

int prime[78498] = {2};
int divisor[15];
char power[15];

void Eratosthenes(int);
int Factorize(long long);
int Exponentiate(int, int);

int main(){

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

    int T; scanf("%d", &T);
    Eratosthenes(999983);

    while(T--){

        long long N; scanf("%lld", &N);
        int sumOfDivisors = 1, numberOfDivisors = 1;

        if(N == 1){
            printf("1 1\n");
            continue;
        }
        int index = Factorize(N);

        for(int i = 0; i <= index; i++){
            numberOfDivisors *= (power[i] + 1);
            numberOfDivisors %= MOD;
        }
        for(int i = 0; i <= index; i++){
            int numerator, denominator;

            numerator = Exponentiate(divisor[i], power[i] + 1);
            numerator = (numerator + MOD - 1) % MOD;

            denominator = Exponentiate(divisor[i] - 1, MOD - 2);

            sumOfDivisors *= (numerator * denominator) % MOD;
            sumOfDivisors %= MOD;
        }
        printf("%d %d\n", numberOfDivisors, sumOfDivisors);
    }
    return 0;
}

void Eratosthenes(int N){

    int i, j, p = 0;
    char list[62501]; memset(list, 0, 62501);

    for(i = 1; ((i * i) << 1) + (i << 1) <= N; i += 1){
        if((list[i >> 3] & (1 << (i & 7))) == 0){
            for(j = ((i * i) << 1) + (i << 1); (j << 1) + 1 <= N; j += (i << 1) + 1){
                list[j >> 3] |= (1 << (j & 7));
            }
        }
    }
    for (i = 1; 2 * i + 1 <= N; ++i){
        if((list[i >> 3] & (1 << (i & 7))) == 0){
             prime[++p] = 2 * i + 1;
        }
    }
}

int Factorize(long long N){

    int index = -1;

    for(int p = 0; prime[p] * prime[p]<= N; p++){
        if(N % prime[p] == 0){
            divisor[++index] = prime[p];
            power[index] = 1;
            N /= prime[p];

            while(N % prime[p] == 0){
                power[index]++;
                N /= prime[p];
            }
        }
    }
    if(N > 1){
        divisor[++index] = N;
        power[index] = 1;
    }
    return index;
}

int Exponentiate(int a, int b){

    int result = 1;

    while(b){

        if(b&1) result = (result * a) % MOD;

        b >>= 1;
        a = ((long long)a * a) % MOD;
    }
    return result;
}