Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
> В числе фибоначи O(N) цифр
Почему вы так решили?
Я не слышал о полезном применении ряда Фибоначчи.
typedef unsigned long long uint64;
uint64 fib_mod_m (uint64 n, uint64 m)
{
uint64 x = 1, y = 0, xx, t;
if (n <= 1)
return n;
int b = 62 - __builtin_clzll(n);
for (; b >= 0; b--)
{
xx = (x * x) % m;
x = (xx + 2 * x * y) % m;
y = (xx + y * y) % m;
if ((n << (63 - b)) >> 63)
{
t = x;
x = (x + y) % m;
y = t;
}
}
return x;
}
Чтобы найти конкретные значения коэффициентов, надо будет добавить условия M0(0,1,1)=0, M1(0,1,1)=1, M0(1,1,1)=1 (чтобы показать, откуда мы начинаем последовательность).
int b = 62 - __builtin_clzll(n);

int mypow(Mat a, int b) {
Mat res;
for (; b; b >>= 1, a *= a)
if (b & 1) res *= a;
return res;
}
>>> def pow(a, b):
... res = 1
... while b:
... if b % 2:
... res *= a
... a *= a
... b /= 2
... return res
def pow(a,b):
res = 1
starta = a
while b:
if b % 2 == 1 :
res *= starta
a *= a
b /= 2
res *= a
return res
def pow(a,b):
res = 1
starta = a
while b:
if b % 2 == 1 :
res *= starta
a *= a
b /= 2
res *= a
return res
static int fastpow(int number, int exp) {
int res = 1;
int startnumber = number;
while ( exp != 0) {
if ( exp % 2 == 1 ) {
res *= startnumber;
exp--;
}
else {
number *= number;
exp /= 2;
}
}
res *= number;
return res;
}
Рекурсивный вариант действительно проще в смысле понимания
static int fastpow(int number, int exp) {
// oddAcc * evenAcc ^ exp = result
int oddAcc = 1;
int evenAcc = number;
while ( exp != 1 ) {
if ( exp % 2 == 0 ) {
evenAcc = evenAcc * evenAcc;
exp/=2;
}
else {
oddAcc = oddAcc * evenAcc;
exp--;
}
}
return oddAcc * evenAcc;
}
Mat pow2(const Mat &a, int b) {
if (b == 0) {
return Mat();
}
Mat res = pow2(a, b / 2);
if (b % 2) {
res *= a;
}
return res;
}
T pow(T a, int n) {
T tmp = n ? pow(a, n/2) : T(1);
return tmp*tmp*(n % 2 ? a : T(1));
}
int pow(int a, int n) {
return n ? (pow(a, n/2) * pow(a, n/2) * (n % 2 ? a : 1)) : 1;
}
«Проще» — очень субъективное понятие. Мне проще написать нерекурсивный цикл...
int pow(int a,int n){
return (n>3 ? pow(pow(a,n/2),2) : (n&2) ? a*a : 1))*(n%2 ? a : 1);
}
void MulFib(double &a0,double &a1,double b0,double b1){
double c=a1*b1+a0*b0;
a0=a1*b0+a0*(b1-b0);
a1=c;
}
double NthFib(int n){
double a0=1,a1=1,b0=0,b1=1;
for(;n;n>>=1){
if(n&1) MulFib(b0,b1,a0,a1);
MulFib(a0,a1,a0,a1);
}
return b0;
}
N-е число Фибоначчи за O(log N)