Простой RecurrenceMax. Оценка 0
Наш герой — Алекс работает над исследованием в течение недели. И у него есть
недавно получил рекуррентное отношение для решения части этого
исследование. Но у него нет времени. Не могли бы вы сделать это?Соотношение рекуррентности выглядит следующим образом: f (n) = 3 * f (n-1) + 2 * f (n-2) + 2
* g (n-1) +3 * g (n-2), g (n) = g (n-1) + 2 * g (n-2).Вам дается начальное значение f (1), f (0), g (1), g (0).
Вы должны вывести f (N) mod 10 ^ 9.
Входные данные:
В первой строке вам даны 4 числа: f (1), f (0), g (1), g (0)
соответственно. В следующей строке вы получите целое число N.
Выход:
Выход f (N) мод 10 ^ 9.
Ограничения:
1 <= f (0), f (1), g (0), g (1) <= 10
1 <= N <= 10 ^ 18
Образец ввода (текстовая ссылка)
1 1 1 1
4
Пример вывода (текстовая ссылка)
162
Это действительно очень простой вопрос. Я просто использовал итерацию с 6 переменными f0, f1, f2, g0, g1, g2 для ее решения. В цикле я сначала вычисляю g2, f2, затем f0 = f1, f1 = f2, g0 = g1, g1 = g2. Типы данных без знака long long в c ++.
Тем не менее, ограничение по времени составляет 1 секунду, и я получаю 1,06 секунды. Поэтому в тесте я прошел только один тестовый пример, другие «превышен лимит времени». Есть ли более быстрый способ решить это?
мой код:
#include<iostream>
using namespace sdt;
int main()
{
unsigned long long f0, f1, g0, g1, f2, g2;
unsigned long long N;
cin>>f1>>f0>>g1>>g0;
cin>>N;
for(unsigned long long i=2; i<N+1; i++)
{
f2=3*f1+2*f0+2*g1*3*g0;
g2=g1+2*g0;
f0=f1;
f1=f2;
g0=g1;
g1=g2;
}
unsigned long long result=f2%1000000000;
cout<<result;
return 0;
}
Данный рецидив можно записать как
с базовыми условиями, заданными f(1)
, f(o)
, g(1)
а также g(0)
, Теперь, чтобы вычислить f(n)
, мы должны поднять матрицу коэффициентов до степени n - 1
, К счастью, это можно сделать с помощью log(n)
умножение матриц. Это известная проблема экспоненцирование.
Поскольку размер матрицы мал, это имеет O(log(n))
сложность.
1-Код отличается от рекуррентного отношения. Код должен быть:
f2=3*f1+2*f0+2*g1+3*g0;
2-Один из возможных способов оптимизации кода — уменьшить количество сложных вычислений, которые в данном случае являются умножением, выполнив следующее:
f2=3*(f1+g0)+2*(f0+g1);
Тем не менее, я думаю, что оптимизатор компилятора сделает это автоматически для вас, но вы можете попробовать себя, чтобы быть уверенным.