Cod sursa(job #2757078)

Utilizator ptlsebiptl sebi ptlsebi Data 3 iunie 2021 20:09:48
Problema Suma divizorilor Scor 70
Compilator c-64 Status done
Runda Arhiva de probleme Marime 1.9 kb
#include <stdio.h>
#include <stdint.h>

void read_uint32_t(FILE *__restrict stream, uint32_t *__restrict nr) {
    uint8_t ch;
    *nr = 0;
    while ((ch = fgetc(stream)) && ('0' <= ch && ch <= '9')) {
        *nr *= 10;
        *nr += ch - '0';
    }
    if (ch == '\r') {
        fgetc(stream);
    }
}

#define MOD 9901

enum DIVISORS {
    DIV, EXP, END
};

uint32_t divs[10][END];
uint32_t divc;

void gdiv(uint32_t a) {
    uint32_t cp;
    if ((a & 1) == 0) {
        cp = 0;
        divc = 1;
        divs[0][DIV] = 2;
        while ((a & 1) == 0) {
            a >>= 1;
            ++cp;
        }
        divs[0][EXP] = cp;
    }
    uint32_t i = 3;
    cp = 0;
    while (a > 1) {
        while (a % i == 0) {
            ++cp;
            a /= i;
        }
        if (cp) {
            divs[divc][DIV] = i;
            divs[divc][EXP] = cp;
            ++divc;
            cp = 0;
        }
        i += 2;
    }
}

uint64_t power(uint64_t o1, uint64_t o2) {
    uint64_t res = 1;
    while (o2 > 0) {
        if (o2 & 1) {
            res *= o1;
            res %= MOD;
        }
        o2 >>= 1;
        o1 *= o1;
        o1 %= MOD;
    }
    return res;
}

uint64_t inv[MOD];

void invers_mod() {
    int32_t i;
    for (i = 1; i < MOD; ++i) {
        inv[i] = power(i, MOD - 2);
    }
}

int main() {
    uint32_t a, b;
    invers_mod();
    {
        FILE *__restrict in = fopen("sumdiv.in", "r");
        FILE *__restrict out = fopen("sumdiv.out", "w");

        read_uint32_t(in, &a);
        read_uint32_t(in, &b);

        gdiv(a);

        uint64_t sum = 1;

        {
            int32_t i;
            for (i = 0; i < divc; ++i) {
                sum *= power(divs[i][DIV], (divs[i][EXP] * b) + 1) + MOD - 1;
                sum *= inv[(divs[i][DIV] - 1) % MOD];
                sum %= MOD;
            }
        }

        fprintf(out, "%llu\n", sum);

        fclose(out);
        fclose(in);
    }
    return 0;
}