Блог пользователя goryinyich

Автор goryinyich, 13 лет назад, По-русски
Решил написать отдельным постом, потому что соответствующая ветка переполнена и вряд ли кто-то в ней заметит.

Сразу хочется сказать - пост нацелен на то, чтобы показать людям, которые ругаются, что контест - маздай, автор контеста - бяка, и как вообще можно давать задачи с непонятной оценкой сложности (типа второй), что они не правы, и после непродолжительных размышлений оказывается, что сложность алгоритма - O(n^2*log(максимальное число)), пусть и с бОльшей константой, нежели при простом бинарном поиске. Этим как раз и хороша задача - она проверяет, действительно ли кодер умеет оценивать сложность, или только знает набор стандартных шаблонов.

Пусть C - это разрыв между максимальным и минимальным числами в нашем наборе, числа могут быть любыми. После не более чем n-1 шагов работы жадного алгоритма (взять минимальное число и проделать, что написано в задаче) мы получаем новое значение разрыва C^ < C*(1-1/n). Почему так? Очевидно, что минимальное число придется увеличить на величину не меньше, чем C/n (в худшем случае - когда еще n-2 числа мимимальны, а последнее - на C больше). Остальные числа, если они оказываются меньше нового минимального - увеличиваются как минимум до его же уровня (а на самом деле - больше, поскольку среднее в это время тоже растет, мы же, из консервативности, зафиксировали его на уровне минимального числа + C/n).

Вот и получается, что за не более чем за n-1 шаг жадного алгоритма разрыв (C) сокращается как минимум до C*(1-1/n). А это все, товарищи! Это означает, что количество шагов жадного алгоритма будет порядка O(n*log(С, логарифм по основанию 1+1/(n-1))), а поскольку каждый шаг - это O(n), то общая сложность - O(n^2*log(максимальное число)), as was stated in the beginning of this outline! Правда, работать это будет чуть дольше, чем бинарный поиск - поскольку логарифм по основанию 1+1/n, то есть в худшем случае порядка 1.02, но константа 1/ln(1.02) ~ 1/0.2 ~ 50 совсем некритична.

P.S. То есть, на самом-то деле, при n --> INF любители математики могут получить, что сложность есть O(n^3*log(max)), предполагая обычный двоичный логарифм и обычную константу, но даже в этом случае при заданных ограничениях задача все равно летает.

Старался объяснить настолько понятно, насколько мог. Если нужно что пояснить - пишите.
  • Проголосовать: нравится
  • +19
  • Проголосовать: не нравится

13 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится
Проблема не в том, что сложность непонятная. Просто некоторые тратили время на контесте на то чтобы доказать, а некоторые сразу сдавали, не задумываясь, насколько быстро их решение будет работать. Эта задача из разряда тех, которые сразу ясно как решать, но чтобы понять, почему это будет достаточно быстро, требуется приложить усилия и потратить на это время.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Ответил ниже, где-то не там записалось =(
  • 13 лет назад, # ^ |
      Проголосовать: нравится +3 Проголосовать: не нравится
    Ну, вот я так рассужал. Вообще-то тут довольно очевидно, если N = 2. Вроде бы с увеличением N ничего больше, чем логарифм, возможно, в некоторой степени, вылазить не должно. Взял да написал, для очистки совести перед сабмитом погонял на больших рандомных тестах.
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Я примерно так же пришел к тому, о чем написал выше. Было чутье, что какой-то логарифм (по основанию меньше 2). Но мог быть риск, что, как вы написали, "возможно, в некоторой степени" - если бы степень была n-1, можно было попасть на TL. Немного покумекал - вывел что-то около формулы выше, и понял, что должно зайти. Потом финально затестил на тесте (46 единиц, 10^16, денег 10^18) - все ок, и заслал (кстати, неплохой тест для отлова неэффективных по времени решений, время работы близко к максимально возможному в этой задаче, мне кажется)
13 лет назад, # |
  Проголосовать: нравится +9 Проголосовать: не нравится
Ну сколько на это нужно времени? Не полматча ведь. Я тратил время на осознавание того, сколько это будет работать, но в итоге все равно успел все решить.
Мне кажется, вполне логичный компромисс - либо не тратишь время, сдаешь вслепую, и есть риск того, что не зайдет, либо думаешь, получаешь чуть меньше баллов, но заходит гарантированно.
Это же СПОРТИВНОЕ программирование - как и в любом спорте, здесь тоже есть разные стратегии, более или менее рискованные.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    На самом деле, в данной задаче вообще был разумный компромис, потому что это спортивное программирование. Никто же не заставлял авторов доказывать оценку сложности для произвольного Н и ограничений. Можно было сгенерить наборы размера 50, рандомные числа порядка 10^15-10^17 и увидеть, что оно нигде не превышает 40к-50к. Понятно, что это не может успокоить человека, которому нужна стопроцентная математическая строгость, но опять таки, это СП:)
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
респект за пост, goryinyich! расставил всё по своим местам; этот медиумосрач уже порядком поднадоел
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Да уж, пробежался я по вашим баталиям... =)

    Только так и не понял, где во второй - длинка? Нужно было только завести отдельную переменную и считать в нее сразу a[i]/n, а остатки a[i]%n кидать в отдельную переменную, которую потом прибавить к ответу для получения необходимого среднего - это 3 лишние строчки кода, поэтому я не понимаю, где здесь преимущество джаверов? А идейно вторая была существенно проще третьей (в ней думать почти не надо было, за исключением оценки сложности и как избежать переполнения, в третьей же все-таки нужно было подинамить), многие просто улетели на аккуратности, но это совсем не повод ставить ее третьей.