powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Пазл с прикольным решением
22 сообщений из 47, страница 2 из 2
Пазл с прикольным решением
    #40100620
Фотография Имя пользователя1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
запихну решение в спойлер.
тут
1) для каждого числа n отрезка 1..N получаем минимальный простой делитель LP(n), за время O(N)

2) для каждого числа n выясняем максимальную степень LP(n) в составе числа, назовем это D(n), например, LP(12) == 2, D(12) = 2 2 = 4.
Можно найти просто циклом (среднее количество итераций которого менее 2, то есть O(1)),
можно использовать предыдущие результаты: если LP(n / LP(n)) === LP(n) , то D(n) = D(n / LP(n)) * LP(n) , иначе D(n) = LP(n) .
Так или иначе, второй этап - O(N)

3) Сумму всех делителей числа n, обозначаемую S(n), можно представить в виде произведения.
Например, n = a x * b y * c z , где a, b, c - простые.
тогда сумма делителей
S(n) = (1 + a + a 2 + ... + a x ) * (1 + b + b 2 + ... + b y ) * (1 + c + ... + c z ) =

= (a x+1 - 1) / (a - 1) * (b y+1 - 1) / (b - 1) * (c z+1 - 1) / (c - 1)


из чего следует S(n) = S(n / D(n)) * (D(n) * LP(n) - 1) / (LP(n) - 1)
в этой формуле мы воспользовались ранее найденым результатом для одного из предыдущих чисел.

----
итого получается O(N) на всё про всё.
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100621
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не нравятся мне эти деления и возведения в степень. Может так случится что мы сложность алгоритма
перенесли на сложность длинной арифметики.
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100624
Фотография Имя пользователя1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Не нравятся мне эти деления и возведения в степень. Может так случится что мы сложность алгоритма
перенесли на сложность длинной арифметики.

ну я сразу обозначил этот момент в стартовом посте:

Имя пользователя1
Насчет размерности чисел не заморачиваемся, полагаем что любое число поместится в некую "числовую переменную", размер и все операции с которой - О(1)

никто тогда не возмутился, значит все согласились )

деления, кстати, тут всегда дают целое число, никаких дробных чисел не будет.
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100630
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имя пользователя1

никто тогда не возмутился, значит все согласились )

деления, кстати, тут всегда дают целое число, никаких дробных чисел не будет.

Никто не то чтобы не возмущался. А все сосредоточились на математической части этой задачи.

Но поскольку форум у нас It-шный то и вопросы - из этой-же области тоже важны.

Какой длины разрядная сетка нужна будет для решения твоей задачи если n = MAX_INT (максимальное целое длиной 32 бита) ?
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100641
Фотография Имя пользователя1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

если ты ещё раз глянешь формулы, то заметишь, что в расчетах никогда не всплывет число, большее искомой максимальной суммы делителей (которая, в свою очередь, менее чем 2N). Итого для N = MAX_INT нужно только 33 бита на число, ну то есть int64 хватит за глаза. Задачка не про длинную арифметику, а про обычную.
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100642
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошо. Убедил. Код давай.
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100664
Gennadiy Usov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Интересно: а где нужна сумма делителей?
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100665
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имя пользователя1,

сомнения есть насчёт O(N) для первого шага
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100675
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
Имя пользователя1,

сомнения есть насчёт O(N) для первого шага


Да здесь предполагается что мы уже знаем таблицу простых чисел до корня квадратного из N.
Или уже есть функция с посчитанной комплексностью которая нам их выдает.

Откуда мы ее знаем? Функцию или таблицу? Или мы ее уже где-то создали? Тоесть в задаче есть
какие-то предварительные договоряки.

Ох уж эти задачки от анонимных преподавателей...
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100723
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

как раз то алгоритм для таблицы простых числе лучше чем за O(N) найти можно - Решето Аткина

но вот как из него найти заявленную функцию, я не могу придумать
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100734
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача пахнет олимпиадной. А для таких задач обычно не нужно привлекать сложные коробочные
алгоритмы или библиотеки. И решение должно быть тоже простое. Прибавить. Отнять. Проверить condition.
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100844
Фотография Имя пользователя1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
Имя пользователя1,

сомнения есть насчёт O(N) для первого шага


да, там вложенный цикл совершенно сбивает с толку. Но не надо поддаваться иллюзии!

Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
const lp = [0, 0, ...., 0]; // индексы от 0 до N
const pr = []; // тут будут простые числа
 
for (let i = 2; i <= n; i++) {
    if (lp[i] === 0) {
        lp[i] = i;  // заполнение элемента lp для простого индекса
        pr.push(i); // добавили i в массив простых
    }
    for (let idx = 0; idx < pr.length && pr[idx] <= lp[i] && pr[idx] * i <= n) {
        const p = pr[idx];
        lp[p*i] := p;  // заполнение элемента lp для НЕ простого индекса
    }
}



Рассмотрим заполнение массива lp.
С простым индексом всё очевидно, он заполняется в ифе на соответствующей итерации внешнего цикла, т.е. один раз.
Если же число i составное, то lp[i] заполнится на внешней итерации j, причем такой, что i == j * p, где p - простое.

Докажем от противного, что такое j только одно для каждого составного i, и любое lp[i] заполняется только один раз.

Допустим, это не так.
Тогда для некоторого i заполнение lp[i] делается на внешних итерациях j1 и j2,
таких что i == (j1 * p1) == (j2 * p2), где p1 и p2 - простые
пусть j1 < j2, тогда p1 > p2
но тогда j1 делится на p2, и значит, LP(j1) < p1, и значит, на внешней итерации j1 внутренний цикл не доберется до простого числа p1 (так как перебираются простые не больше LP(j1)), и не будет затронута ячейка lp[i].
Противуречие.

итак, каждое lp[i] заполняется только один раз. Поскольку во внутреннем цикле каждая итерация заполняет ячейку lp, то всего итераций всех внутренних циклов не более чем n.
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100848
Фотография Имя пользователя1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то перемудрил, можно проще)

Рассмотрим заполнение массива lp.
С простым индексом всё очевидно, он заполняется в ифе на соответствующей итерации внешнего цикла, т.е. один раз.
Если же число i составное, то lp[i] может заполнится только на внешней итерации вида j == i/p, где p - некоторый простой делитель i.
Заметим, что здесь p <= LP(j), так как во внутреннем цикле перебираются только такие p. Получается, p == LP(i), тогда j = i/LP(i), то есть такое j возможно только одно для каждого i.

Итого, каждое lp[i] заполняется только один раз. Поскольку во внутреннем цикле каждая итерация заполняет ячейку lp, то всего итераций всех внутренних циклов не более чем n.
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100874
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имя пользователя1,

пардонс, увидел, браузер по ссылке не показал место с доказательством
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100894
Фотография Имя пользователя1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan),

Ага, в Википедии не доказано. Но этот алгоритм хотя бы упоминается, в английской версии его вообще нет )
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100895
Фотография Имя пользователя1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
А для таких задач обычно не нужно привлекать сложные коробочные
алгоритмы или библиотеки.
насколько я знаю, в спортивном кодинге можно юзать только стандартную библиотеку языка. Но без багажа алгоритмов там каши не сваришь, это всё равно что без дебютной базы пытаться в серьёзные шахматы.
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100898
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имя пользователя1
mayton
А для таких задач обычно не нужно привлекать сложные коробочные
алгоритмы или библиотеки.
насколько я знаю, в спортивном кодинге можно юзать только стандартную библиотеку языка. Но без багажа алгоритмов там каши не сваришь, это всё равно что без дебютной базы пытаться в серьёзные шахматы.

Я видел олимпиады на Турбо-Паскале. Какая там стандартная библиотека? Решета Аткина там точно нету.
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100904
Фотография Имя пользователя1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Я видел олимпиады на Турбо-Паскале. Какая там стандартная библиотека?
на плюсах, к примеру, в std есть дохрена ништяков. Кучи, деревья, списки, и т.д.

mayton
Решета Аткина там точно нету.
в сабжевом паззле, кстати, его тоже не найти. Есть простой код на 10 строк, который только что разобрали по косточкам.
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100909
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А где в этом коде результат? Я имею в виду число с наибольшей суммой делителей.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
const lp = [0, 0, ...., 0]; // индексы от 0 до N
const pr = []; // тут будут простые числа
 
for (let i = 2; i <= n; i++) {
    if (lp[i] === 0) {
        lp[i] = i;  // заполнение элемента lp для простого индекса
        pr.push(i); // добавили i в массив простых
    }
    for (let idx = 0; idx < pr.length && pr[idx] <= lp[i] && pr[idx] * i <= n) {
        const p = pr[idx];
        lp[p*i] := p;  // заполнение элемента lp для НЕ простого индекса
    }
}



P.S. И на каком это языке кстати?
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100931
Фотография Имя пользователя1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Если что, обсуждался алгоритм из Википедии (который в п.1 решения). Руслан спросил о линейности алгоритма, я расписал почему считаю этот алгоритм линейным. Полный код чуть позже запилю.
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40100942
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот так... поманил конфетой.

Давай уже как только так сразу и выкладывай.
...
Рейтинг: 0 / 0
Пазл с прикольным решением
    #40101019
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

да там накатать то проблем нет, в два этапа выходит алгоритм работает, первый шаг в вики неплохо описан
2-й и 3-й совмещаются в один цикл
...
Рейтинг: 0 / 0
22 сообщений из 47, страница 2 из 2
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Пазл с прикольным решением
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]