На предыдущем контесте (Round #177, div.2) случилось страшное, однако для меня обыденное — задача С, по которой я сделал шесть взломов у меня упала по TL. Вот код.
Я, перечитав код, начал пенять на сложение строк. Скажите, это оно виновато в моем горе, или я неправ, и ошибка в другом? Если это сложение строк, то скажите, почему оно так долго работает?
Спойлер: массив "a" не имеет применения в данном коде.
UPD: операция "+" для строк для работает за линию.
Будьте бдительны!
Тут написано "Complexity: Unspecified, but generally up to linear in the new string length."
Это кошмар и ужас. Но зато теперь буду знать. Спасибо.
Это сложность выполнения одной операции. Амортизированная сложность кучи сложений будет видимо близка к O(итоговая длина).
s = (char)('a' + i) + s;
Вот здесь это точно будет квадрат.
Это относится к тем же приколам, что бывают с векторами. То есть в случае, когда нужно сделать реаллокацию, сложность действительно будет O(new_length). В остальных случаях O(1). То есть амортизированная сложность в итоге будет O(length).
И действительно:
В случае строк посмотрим на оператор +:
И на оператор +=:
То есть ваш код работал за квадрат, так как создавался объект на основе первой строки, затем уже к нему добавлялась вторая строка. В случае строк лучше делать +=. Так как не создаются объекты, если они нам не нужны, а работает, как push_back в массиве.
Странно пенять на операцию "+=", которой в вашем коде вообще нет. Эта операция работает быстро. У вас же каждый раз выполняется простое присваиваение s = s+один_символ. Это, конечно, работает долго.
Да, "+=" было странной опиской, спасибо
Всю жизнь строки складывал так же, как ты. Спасибо за подсказку, больше так делать не буду :3
Понятно же, что
s = t + s
будет работать за квадрат. Нельзя просто так взять и дописать элементы спереди. Если уж очень надо, тоdeque<char>
какой-нибудь поможет, наверно.Ну такого там нет. Там все-таки
s = s + t
, но только суть от этого не меняется. Не знаю, как в джаве, но в плюсах точно происходит создание того, что я описал выше. В принципе могу выложить сюда и код того, как работаетappend
, но это вряд-ли целесообразно, у всех он и так есть :)UPD.
s = t + s
там тоже есть, но таких операций не более, чем k. То есть мало.В джаве строка — неизменяемый объект, поэтому там всегда при сложении создаётся новый объект.
Наверное имелся в виду StringBuffer / StringBuilder