Cod sursa(job #1900875)

Utilizator 1475369147896537415369Andrei Udriste 1475369147896537415369 Data 3 martie 2017 17:11:03
Problema Suma si numarul divizorilor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.68 kb
#include <cstdio>
#include <iostream>
#include <string.h>
#include <cmath>
using namespace std;
#define MOD 9973

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

void Eratosthenes(int);
int Factorize(long long);
void ModularInverse(int, int, 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 = 1, denominator, x, y;

            for(int j = 1; j <= power[i] + 1; j++){
                numerator *= divisor[i];
                numerator %= MOD;
            }
            numerator = (numerator + MOD - 1) % MOD;
            denominator = divisor[i] - 1;

            ModularInverse(denominator, MOD, x, y);
            if(x <= 0) x = MOD + x % MOD;
            denominator = x;

            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 sqrtN = (int)sqrt(N);
    int index = -1;

    for(int p = 0; prime[p] <= sqrtN; 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;
}

void ModularInverse(int a, int b, int &x, int &y){

    if(!b){
        x = 1;
        y = 0;
    }else{
        int x0, y0;
        ModularInverse(b, a % b, x0, y0);
        x = y0;
        y = x0 - (a / b) * y0;
    }
}