Cod sursa(job #3289153)

Utilizator tudordaianDaian Tudor tudordaian Data 25 martie 2025 21:14:34
Problema Suma divizorilor Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.72 kb
#include <iostream>
#include <vector>
using namespace std;

typedef long long LL;
const int mod = 9901;

/*
    Brutal.
    Daca d e un divizor, atunci el apare de n / d ori.
    n = 12.
    1 + 2 + 3 + 4 + 6 + 12 = 28
    fie div d = 3. El se regaseste si in 6 si in 12, adica apare de 3 ori, adica de n / d ori
    Pt 12, suma div = 1 + 2 + 3 + 4 + 6 + 12 = 28
    1: apare la 1 * 1, 1 * 2, 1*3, 1*4, 1*6, ... de (12 / 1) ori. +12 => 12
    2: apare la 1 * 2, 2 * 2, 3 * 2, 6 * 2, de 4 ori. +8 => 20
    3: apare la 1 * 3, 2 * 3, 4 * 3,  de 3 ori. +9 => 29

    Ce factori au aparut de mai multe ori ?
    impartiti factorii in doua categorii: cei de dinainte de radical(n) si cei de dupa
    FAceti o implementare corespunzatoare acestei idei.


    Mai bine:
    Mica Teorema a lui Fermat: a^(p - 1) = 1 (mod p)
    a^(p - 1) / a = 1 / a (mod p) <=> a^(p - 2) = a^(-1) mod p
    (nr / a) (mod p) = ( nr * a^(p-2) ) (mod p) = {(nr (mod p)) * (a^(p-2) mod p)} (mod p)
*/

/// vreau sa retin factorul prim si puterea la care apare
vector<int> prime;
vector<int> puteri;
inline void descompune( LL x )
{
    LL cnt;
    for( LL i = 2; i * i <= x; ++i )
        if( x % i  ==  0 )
            {
                prime.push_back( i );
                cnt = 0;
                while( x % i  == 0 )
                    {
                        x = x / i;
                        ++cnt;
                    }
                puteri.push_back( cnt );
            }
    if( x  >  1 ) /// Termin chiar cu un factor prim
        prime.push_back( x ), puteri.push_back( 1 );
}

inline LL exponentiere_rapida( LL A, LL B )
{
    LL rasp = 1;
    while( B != 0 )
        {
            if( B & 1 )
                rasp = (rasp * A) % mod;
            A = (A * A) % mod;
            B = (B >> 1);
        }
    return rasp;
}

/// Atentie, exista supradepasire a tipului de date! De ce esueaza pt valori mari ale lui B?
/// Explicati-va expresiile matematice.

/// Faceti modificarile necesare (CAT MAI PUTINE!) ca sa va dea raspunsul corect!

int main()
{
    LL A, B, rasp = 1;
    cout << "A = "; cin >> A;
    cout << "B = "; cin >> B;

    descompune( A );

    int d = prime.size(), i;
    for( i = 0; i < d; ++i )
        {
            puteri[ i ] = B * puteri[ i ];
            if( (prime[i] - 1 ) % mod == 0 )
                rasp = rasp * (puteri[i] + 1) % mod;
            else
                {
                    LL termen1 = ( exponentiere_rapida(prime[i], puteri[i] * B - 1) - 1 ) % mod;
                    LL termen2 = ( prime[ i ] - 1 ) % mod;
                    rasp *= termen1 / termen2;
                    rasp %= mod;
                }
        }

    cout << rasp;

    return 0;
}