Python

Решение задачи по программированию (желательно питон) Сложность O(квадрат(n))

Прохожу задачи яндекс алгоритмов 2018 для тренировки. Никак не могу понять задачу. Вот её содержание и решение. Помогите с кодом, не могу правильно его написать.

Содержание:


Алексей регулярно проводит собеседования с кандидатами на позицию стажёра. И хотя он провёл уже не одну сотню собеседований, в последнее время этот процесс даётся ему нелегко — кандидаты стали без труда решать все годами протестированные и отработанные задачи Алексея!


Делать нечего, и в преддверии очередного собеседования Алексей придумал новую задачу. Имеется числовая последовательность, на первом шаге состоящая из двух чисел 1. На каждом шаге следующем шаге между каждыми двумя соседними элементами добавляется новый элемент, равный их сумме. После первых нескольких шагов последовательность выглядит следующим образом:
1 1
1 2 1
1 3 2 3 1
1 4 3 5 2 5 3 4 1


На собеседовании Алексей хочет попросить кандидата написать программу, которая по заданному числу $n$ будет определять, сколько раз число $n$ будет встречаться в последовательности на $n$-м шаге? Алексей ещё не научился решать свою задачу, но слышал, что кандидат, которого он будет сейчас собеседовать, добился высоких результатов в спортивном программировании, поэтому, скорее всего, легко справится с этим вопросом.

Решение:

Пусть мы имеем числа $pq$, стоящие рядом на некотором шаге и пусть $p>q$ (без ограничения общности). Тогда $p$ было получено как сумма $p-q$+$q$, то есть на предыдущем
шаге рядом стояли $p-q$ и $q$. Если $p-q < q$, то два шага назад справа от $q$ стояло число $2q-p$, если $p-q > q$, то слева от $p-q$ стояло число $p-2q$ и так далее. Так как $p$ и $q$
взаимно просты, то на каком-то шаге этот процесс, по сути являющийся разновидностью алгоритма Евклида, приведёт к тому, что с одной стороны окажется $1$, а с другой — некоторое
натуральное число. Но пара $(1,x)$ или $(x,1)$ для любого $x$ будет соседней последовательности на $x$-м шаге. А так как действия восстанавливаются однозначно,
то это значит, что и исходная пара $(p,q)$ в какой-то момент встретится в качестве соседней.


Таким образом, каждая упорядоченная пара взаимно простых чисел ровно один раз встречается в качестве соседей в заданной последовательности. Поэтому задача сводится к подсчёту количества упорядоченных пар взаимно простых чисел, дающих в сумме $n$. Так как если $p$ и $n$ взаимно просты, то и $p$ и $n-p$ взаимно просты, то количество таких пар можно поставить в однозначное соответствие количеству чисел, взаимно простых с $n$, или значению функции Эйлера от $n$.


Подсчёт же количества таких чисел является известной задачей и опирается на мультипликативность функции Эйлера: если $n=p_1^{k_1} \cdot p_2^{k_2} \cdot \ldots \cdot p_n^{k_n}$, то взаимно простых с $n$
чисел будет $(p_1^{k_1}-p_1^{k_1-1}) \cdot (p_2^{k_2}-p_2^{k_2-1}) \cdot \ldots (p_n^{k_n}-p_n^{k_n-1})$. Раскладываем $n$ на простые множители за время
У тебя неправильно считается твой массив (хотя тут, насколько я понимаю, решать надо вообще не через массивы, а через функцию Эйлера, ну да ладно - в лоб, так в лоб) - тут простыми итераторами не обойдешься, нужно включать мозг. Код на c#:

int n = int.Parse(Console.ReadLine());
List< int > a = new List< int >() { 1, 1 };
for (int i = 1; i < n; i++)
{
int k = 1;
while (k < a.Count)
{
a.Insert(k, a[k - 1] + a[k]);
k += 2;
}
foreach (int x in a)
Console.Write($"{x} ");
Console.WriteLine();
}

Console.WriteLine(a.Count(x => x == n));

Console.ReadLine();
Sasha Sasha
Sasha Sasha
95 342
Лучший ответ
Антон Должиков Спасибо огромное!
1)
Не "Сложность O(квадрат (n))", а "Сложность O(корень (n))" - разница примерно как "небо" и "земля".

2)
Вы не упоминаете, как нечто неважное, диапазон N, но там в задачке он ясно указан как
1 <= n <= 10^13
Насколько я понял, Вы собрались создать список соответствующий этому N, а затем с помощью какого-нибудь list.count(n) найти ответ.
А Вас не смущает, что получиться список в котором будет порядка триллиона элементов?
А учитывая, что каждый список Вы создаете из предыдущего, используя самый неэффективный для этого insert(), то у Вас получиться не просто триллион, а пожалуй в квадрате, если не в кубе.

Попробуйте это:
https://pastebin.com/bqn0qxAr
Sergei
Sergei
21 729
Sergei " получиться список в котором будет порядка триллиона элементов"

Это я ошибся.
Триллион - это не количество элементов списка, а количество нулей в записи числа этого количества.
Антон Должиков 1.Со сложностью ошибся, виноват
2.Думал диапазон не имеет особого значения
Антон Должиков Огромное спасибо!