Pagini recente » Cod sursa (job #1092051) | Cod sursa (job #3159226) | Cod sursa (job #3250573) | Cod sursa (job #3229481) | Cod sursa (job #3289153)
#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;
}