Dobra, wytłumaczę Ci to, ale się Nauczysz i następne Robisz sam:). Zadania na SPOJu nie są takie, że wpisac byle co i wysłać, trzeba się trochę pomęczyć ze złożonością:). Jakbyś Czytał to co koledzy piszą, to na kartce powinieneś dojść, co najmniej, do naiwnego rozwiązania (które na 100% nie przejdzie):
int mod_power1(int a, int n, int mod){
int p = 1;
for (int i = 0; i < n; i++){
p = (a * p) % mod;
}
return p;
}
Jak widać złożoność jest O(n)
, dalej za dużo przy liczbach do miliarda. Trzeba lepiej potęgować, chyba najłatwiejszy z algorytmów dziel i rządź i jednocześnie efektywny jako potęgowanie, to: squaring exponentiation. Łatwo go przepisać do wersji z modulo, trzeba sobie tylko dodać funkcję mnożenia mod:
int mod_mul(int n, int m, int mod){
return ( (n % mod) * (m % mod)) % mod;
}
int mod_power2(int a, int n, int mod){
if (n == 1) {return a % mod;}
else if (n % 2 != 0){
return mod_mul(a, mod_power2(mod_mul(a, a, mod), (n - 1) / 2, mod), mod);}
else{
return mod_power2(mod_mul(a, a, mod), n / 2, mod);}
}
Kod nie jest optymalny, ale złożoność jest O(logn)
, na SPOJU na pewno przejdzie:).