Я пытаюсь решить эту проблему: SPOJ problem.Поиск n-го числа фибров, в O (logn)
И после некоторых исследований выяснилось, что это сводится к простому вычислению n-го числа фидов, однако n может стать действительно большим, поэтому решение O (n) не принесет пользы. Погуглить вокруг, я обнаружил, что вы можете вычислить п-е число Фибоначчи в O (LogN), а также пример кода, который делает именно то, что:
long long fibonacci(int n)
{
long long fib[2][2]= {{1,1},{1,0}},ret[2][2]= {{1,0},{0,1}},tmp[2][2]= {{0,0},{0,0}};
int i,j,k;
while(n)
{
if(n&1)
{
memset(tmp,0,sizeof tmp);
for(i=0; i<2; i++) for(j=0; j<2; j++) for(k=0; k<2; k++)
tmp[i][j]=(tmp[i][j]+ret[i][k]*fib[k][j]);
for(i=0; i<2; i++) for(j=0; j<2; j++) ret[i][j]=tmp[i][j];
}
memset(tmp,0,sizeof tmp);
for(i=0; i<2; i++) for(j=0; j<2; j++) for(k=0; k<2; k++)
tmp[i][j]=(tmp[i][j]+fib[i][k]*fib[k][j]);
for(i=0; i<2; i++) for(j=0; j<2; j++) fib[i][j]=tmp[i][j];
n/=2;
}
return (ret[0][1]);
}
Я попытался изменить его проблемы, и я все еще получаю WA: http://ideone.com/3TtE5m
Я неправильно вычисляю модульную арифметику? Или это еще одна проблема?
Fibbonacci или prime? – EvgeniyZh
Для проблемы SPOJ используйте fib (n + 1), за исключением n = 0, я не уверен, что 0 монет считается одним способом. Обратите внимание, что (x% 12345678901) * y (% 12345678901) может потребовать до 68 бит. В 64-битном режиме может быть реализована функция на основе сборки для умножения по модулю 12345678901, поскольку продукт после умножения и деления до деления может составлять 128 бит. – rcgldr