Cod sursa(job #3327108)

Utilizator EricDimiCismaru Eric-Dimitrie EricDimi Data 2 decembrie 2025 11:41:21
Problema Suma divizorilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.17 kb
#include <fstream>
#include <cmath>

using namespace std;

ifstream f("sumdiv.in");
ofstream g("sumdiv.out");

typedef unsigned long long uLLong;

const int MOD = 9901,
          MOD1 = MOD - 1;
/// a^(MOD - 1) ≡ 1 (mod MOD) - Teorema lui Fermat

int pwr(uLLong a, uLLong n)
{
    int r = 1, x  = a % MOD;
    while (n > 0)
    {
        if (n & 1)
            r = (uLLong)r * x % MOD;
        x = (uLLong)x * x % MOD;
        n >>= 1;
    }
    return r;
}

inline int invMod(uLLong a)
{
    return pwr(a, MOD - 2);
}

/**
void EuclidExtins(uLLong a, uLLong b, uLLong &d, uLLong &x, uLLong &y)
{
    if (b == 0)
    {
        d = a;
        x = 1;
        y = 0;
    }
    else
    {
        uLLong x0, y0;
        EuclidExtins(b, a % b, d, x0, y0);
        x = y0;
        y = x0 - (a / b) * y0;
    }
}

int invMod(uLLong a)
{
    uLLong d, x, y;
    EuclidExtins(a, MOD, d, x, y);
    x %= MOD;
    if (x < 0)
        x += MOD;
    return x;
}
*/

uLLong sumdiv(uLLong A, uLLong B)
{
    uLLong rad = (uLLong)sqrt(A),
           B1 = B % MOD1,
           sum = 1;
    int p;
    for (uLLong d = 2; d <= rad; d++)
        if (A % d == 0)
        {
            p = 0;
            do
            {
                p++;
                A /= d;
            }
            while (A % d == 0);
            if (d % MOD == 0)
                continue;
            if (d % MOD != 1)
            {
                sum = (uLLong)sum * ((uLLong)pwr(d, (B1 * p + 1) % MOD1) + MOD - 1) % MOD;
                sum = (uLLong)sum * invMod(d - 1) % MOD;
            }
            else
                sum = (uLLong)sum * ((B % MOD) * p + 1) % MOD;
        }
    if (A > 1)
    {
        if (A % MOD == 0)
            return sum;
        if (A % MOD != 1)
        {
            sum = (uLLong)sum * ((uLLong)pwr(A, (B1 + 1) % MOD1) + MOD - 1) % MOD;
            sum = (uLLong)sum * invMod(A - 1) % MOD;
        }
        else
            sum = (uLLong)sum * ((B % MOD) + 1) % MOD;
    }
    return sum;
}

int main()
{
    uLLong A, B;
    f >> A >> B;
    g << sumdiv(A, B);
    f.close();
    g.close();
    return 0;
}