если вы имеете в виду наименее значимые или самые правые цифры, это можно сделать с помощью модульного умножения.Это сложность O (N) и не требует специальных типов данных bignum.
#include <cmath>
#include <cstdio>
//returns ((base ^ exponent) % mod)
int modularExponentiation(int base, int exponent, int mod){
int result = 1;
for(int i = 0; i < exponent; i++){
result = (result * base) % mod;
}
return result;
}
int firstKDigitsOfNToThePowerOfN(int k, int n){
return modularExponentiation(n, n, pow(10, k));
}
int main(){
int n = 11;
int result = firstKDigitsOfNToThePowerOfN(3, n);
printf("%d", result);
}
Это выведет 611, первые три цифры 11 ^ 11 = 285311670611.
Эта реализацияподходит для значений N меньше, чем sqrt (INT_MAX), которые будут варьироваться, но на моем компьютере и языке оно превышает 46 000.
Более того, если так получится, что ваш INT_MAX меньше (10 ^ k) ^2, вы можете изменить modularExponentiation для обработки любого N, который может поместиться в int:
int modularExponentiation(int base, int exponent, int mod){
int result = 1;
for(int i = 0; i < exponent; i++){
result = (result * (base % mod)) % mod; //doesn't overflow as long as mod * mod < INT_MAX
}
return result;
}
, если O (n) времени недостаточно для вас, мы можем воспользоваться свойством возведения в степень, что A ^ (2 * C) = (A ^ C) ^ 2 и получить логарифмическую эффективность.
//returns ((base ^ exponent) % mod)
int modularExponentiation(int base, int exponent, int mod){
if (exponent == 0){return 1;}
if (exponent == 1){return base % mod;}
if (exponent % 2 == 1){
return ((base % mod) * modularExponentiation(base, exponent-1, mod)) % mod;
}
else{
int newBase = modularExponentiation(base, exponent / 2, mod);
return (newBase * newBase) % mod;
}
}