Предлагаю здесь обсудить задачи прошедшего Гран-При.
Интересно узнать решение задачи K.
№ | Пользователь | Рейтинг |
---|---|---|
1 | tourist | 4009 |
2 | jiangly | 3823 |
3 | Benq | 3738 |
4 | Radewoosh | 3633 |
5 | jqdai0815 | 3620 |
6 | orzdevinwang | 3529 |
7 | ecnerwala | 3446 |
8 | Um_nik | 3396 |
9 | ksun48 | 3390 |
10 | gamegame | 3386 |
Страны | Города | Организации | Всё → |
№ | Пользователь | Вклад |
---|---|---|
1 | cry | 167 |
2 | maomao90 | 163 |
2 | Um_nik | 163 |
4 | atcoder_official | 161 |
5 | adamant | 159 |
6 | -is-this-fft- | 158 |
7 | awoo | 157 |
8 | TheScrasse | 154 |
9 | nor | 153 |
9 | Dominater069 | 153 |
Предлагаю здесь обсудить задачи прошедшего Гран-При.
Интересно узнать решение задачи K.
Название |
---|
Ссылку на Гран-При в студию.
http://opencup.ru/
K
Напишем префикс суммы. Пусть мы остановились в местах с префикс-суммами a_1, .. a_k, тогда надо посчитать |a2-a1| + |a3-a2| + ..., ну а минимум этого достигается при монотонном проходе по префикс сумма, что-то типа a_(k + i +/-1) — a_(i) в посорченном массиве.
Да уж. Мы глупые(
К: заменяем массив на префикс-суммы, дальше у нас есть просто граф с n вершинами, пройти по ребру (i, j) стоит |a[i] - a[j]|, нужно найти самый дешевый путь длины k - 1. Сортим вершины по a[i] и перебираем, какой подотрезок возьмем в качестве пути.
Прямо как у нас решение:D
Вопрос днища: как решается A, D и H?
D: Чтобы понимать в какую часть мы попадаем на i-ом разделении нужно смотреть i-ый слева бит числа k - 1. При этом последние примерно 60 битов проверяем ручками, а среди первых n - 60 — все биты 0, а значит [(n — 60 + 1)/2] раз добавится к A, и [(n — 60)/2] к B.
H: Общий случай: пусть компания получила p%, тогда 2p% = (после сокращения) поставлено на проигравших и на победителей. У нас ограничения только сверху, поэтому можно считать, что всего ставок y, теперь если y - x > k или k·(n - 1) < x, то все плохо, иначе все хорошо распределяется.
Осталось понять, что 50% получить невозможно, а 100% соответствует нашему решению для 50% — 0 поставлено на победителя.
А что здесь является y?
Скорее более 49 и менее 100 не можем получить.
Для >50 автоматически получится ( если проверку y - x > = 0 сделать), так что более менее без разницы
А: сначала решим такую подзадачу: для числа n посчитать f(n) — число способов разбить на 3 неупорядоченных слагаемых. Это . Первое слагаемое получено по формуле включения-исключения и включает варианты, когда все 3 числа различны, второе слагаемое — когда среди трех есть совпадающие.
Дальше, учитывая, что f(n) не убывает, используем бинарный поиск для нахождения обеих границ. Ответ — некоторый подотрезок натурального ряда.
расскажите E, K и J
J: Про каждого человека, когда мы его берем в текущий состав, достаточно понимать, сколько подряд единиц у него с этого момента(чем больше, тем лучше), ибо его все равно перед его нулем нужно убрать и лучше, чтобы он мог продержаться как можно больше.
Теперь решение: сперва динама
dp[man][pos]
сколько с этого момента единиц у человека. Потом выбираем k лучших поdp[man][0]
и на каждом шаге проверяем, что в команде все сdp[man][pos] > 0
, выкидываем худшего на данным момент и выбираем лучшего из тех, кто не в команде.Ох чёрт, а я поток написал зачем-то.
А какой там поток?
[количество раундов слоёв], для каждого слоя:
[2 * количество чуваков] вершин + 2 вершинки для замены.
2 чтобы ограничение на вершину было, а не на ребро, стандарт короче.
Ребра тоже понятно как ставить: чувак либо остается на следующий уровень, либо ребро в замену. Из замены ребра во всех людей на следующем уровне.
Ну и ищем поток величины ровно k.
Ага, спасибо.
isnt 2e5 nodes too much for flow?
there's 2e5 nodes, and about that number edges. Easiest flow works in
O(flow * edges)
and flow is 100Можно жадно: в начале сортируем людей по количеству единиц подряд на префиксе, а дальше после каждого вопроса выбрасываем человека с самым маленьким количеством единиц и берем с наибольшим количеством единиц на текущем префиксе (без учета уже прошедших раундов).
E: Вероятность сменить позицию у встречных людей с L->R или с R->L это . Дальше вроде понятно все. Считаем вероятность нахождения слева и справа для нас и к матожиданию в силу линейности прибавляем вероятности столкновения.
научите решать тервер
Да ладно, зачем вам тервер. Всё же без него решается, смотрите:
Первые вероятости считаем просто возведением матрички в степень, все умеют, практикуют.
Затем нужно мат. ожидание посчитать. Тут несколько сложнее. Напишем очевидную динамику: d[i][j][side] -- вероятность после i встреч сменить стороны j раз и оказаться на стороне side. Правда в ней O(N^2) состояний, но это не беда, первое нам не нужно, храним два слоя.
Осталось со временем разобраться, ведь тоже квадрат же.
Но и тут можно не думать: интиутивно понятно, что интересных состояний с d[j][side] > eps (1e-18 в моём случае) будет не так уж и много, наверно.
Пишем, проверяем, ага, ~1000, сдаём за 0.95 с плюса при TL'е в секунду.
Исходник: http://pastie.org/9095343
Да, посоветуйте книжку по терверу пожалуйста, тяжело быть тупым, кода писать много приходится.
Ну когда первые вероятности посчитаны с помощью матричек, то теорвер никакой и не нужен, разве что свойство линейности мат ожидания.
Раз матожидание линейно, то для каждого возможного перехода на другую сторону можно отдельно посчитать вероятность, что он произойдет, а потом просуммировать их. А именно, посчитаем динамику dp[i][side] — вероятность оказаться на стороне side после i первых встреч. Теперь зафиксируем i встреч, которые уже произошли, side — сторону, на которой мы оказались. Вероятность того, что в таком состоянии случится переход на другую сторону, равна dp[i][side] * (вероятность того, что i-ый человек будет на стороне side при встрече). Просуммируем все такие значения — профит.
what was the 9th test in h problem?
Case with P = 100 and any N and K.
Как решать B?
Например так.
Сначала наивное решение. Построим 3 бора, в каждом боре в вершине сохраним сет номеров строк. Тогда каждый запрос характеризуется тройкой чисел — номерами вершин в 3 борах. Ответ — это размер пересечения трех сетов.
Теперь корневая оптимизация. Для каждой вершины бора, если размер сета больше sqrt(N), то заменим его на битсет. То есть вершина бора у нас будет примерно такой:
В итоге имеем, что каждая вершина бора или "тяжелая" (а таких не больше корня, то есть памяти нам хватит), или "легкая" (их суммарный размер не больше 105 по условию). Значит, памяти хватает.
Теперь при ответе на запрос если у нас во всех 3 вершинах сеты, то просто используем set_intersection(), если все битсеты — то используем побитовый and битсетов и используем bs->count(), а если есть и сеты, и битсеты, то пересекаем сеты, а потом проходимся по сету и проверяем, есть ли элемент в битсете.
Вроде это работает за O(Nsqrt(N)) — на онсайте за секунду зашло.
The translation says "construct 3 boron" actually what did you mean? suffix array/automaton or something else? a bit translation would be great. or may be source code (its universal language :))?
It was a trie.
А почему это не n ^ 2 / 64? Если так, то корневая не нужна, с нехваткой памяти можно бороться более простым способом. Просто разобьем все id на группы по k штук, для каждой группы будем решать отдельно. Использовать будем только битсеты. В каждом битсете, лежащем в вершине бора, будет использоваться k / 64 памяти, что в сумме мало. Обработаем все запросы для данной группы за q * k / 64. В сумме получим n * q / 64. Нам пришлось немного попихать в дорешку, но все-таки зашло.
В этой задаче самым важным является тот факт, что число полей К не больше трех.
Для каждого из 3 полей сохраним все возможные его строчки и запросы в боре. Занумеруем вершины каждого бора в порядке обхода dfs'а. Теперь каждый ID туриста характеризуется 3 числами — позициями соответствующих вершин в порядке обхода, назовем их x, y, z, тогда ID будет точкой в трехмерном пространстве. Запрос так же характеризуется 3 вершинами, и ответом на запрос является число таких ID, что соответствующие ему вершины лежат в 3 поддеревьях вершин запроса. Так как мы пронумеровали все вершины бора в порядке обхода, то в одном поддереве будут лежать вершины с последовательными номерами от L до R. Зная такие границы для каждой вершины, можно ввести ограничения на каждую координату искомых точек и свести запрос к задаче нахождения количества точек внутри параллелепипеда.
Ну эту задачу вроде уже можно решать разными способами, например, оффлайн деревом отрезков декартовых деревьев:)
Мы так же делали, но раз уж оффлайн, можно вместо декартовых использовать фенвика.
Since, N ~ 1e5, how will you do 2d-range-query (for sweeping one dimension will be reduced) in Fenwick tree? Don't you need 2D BIT?
You can use 2-D Fenwick tree, which is very easy to implement. Just compress the first coordinate and for each valid first coordinate maintain a Fenwick tree by the compressed second coordinate in a separate vector.
Понравелось задание "H", но если в условиях было бы
0 < A[i] <= K
, стало бы интересней.А чем интересней? Прибавим ко всем единичку, а потом тоже самое.
Мне показалось, что надо считать хватит ли этих единичек, и для того подберать максимальные числа, непревышающие
k
.В любом случае давайте ко всем прибавим единичку и теперь мы решаем ту же задачу только с K на единицу меньше.
Был неправ, согласен. Как говорят — дошло.
if P==100
1
0 0 0 0 ... 0 is true?
There was clarification, that there should be at least 1 bet
At least must be one i that A[i] >= 1.
P.S. If you write in english write not to russian thread (it's second time).
ok,but what is answer for P=100?
for example
1
1 0 0.. 0
Thanks
It's P == 0.
yes, sure, thanks, so the answer is
2
1 0 0 0 0..
and impossible for
n = 1
(I don't remember if it's allowed)Видимо, сдвоенный опенкап — не очень хорошая идея.
Когда победитель определяется за 2 тура до конца, следующие 3 места за тур до конца, это не есть хорошо.
Вот даже из пяти участников Petr Team ни у кого не нашлось мотивации написать сегодня последний тур :(.
Участников Petr team слегка раскидало по миру просто
Не надо, это не проблема в наше время. Есть возможность и досрочно написать.
Уверен, что, если бы вы имели шансы на 1-е место, то точно нашли бы возможность.
Я это не вас критикую, а формулу соревнования. Если бы было 7+7, то результат был бы оба раза не ясен до разморозки последнего тура.
Мне скорее кажется не очень удачной идеей два или более этапа подряд (с интервалом в неделю). Мне кажется, было бы легче найти мотивацию поучаствовать, если бы минимальный интервал между этапами был хотя бы 3 недели.
В мае сессия у студентов, туда тоже не особо хочется этапы назначать
Понимаю — но можно ведь уменьшить число этапов, или хотя бы число зачётных этапов до, скажем, 8-10 за год?..
Просто Кубок как-то занимает почти весь день — пока доедешь до сектора, пока напишешь, пока пообедаешь после и вернёшься из сектора...
Поэтому писать каждое воскресенье довольно напряжно.
Уменьшать число этапов понятно, что плохо, ведь есть те, кому хочется побольше писать, зачем их обламывать. А вот количество зачетных этапов вполне можно уменьшить, можно попробовать со снарком поговорить на эту тему
Да, согласен. В принципе достаточно, чтобы зачетными были половина этапов плюс один — тогда уже нет шанса на два абсолютных результата. То есть в нынешнем кубке это было бы 8 этапов.
------------------------------- Странная идея, по-моему.
Я изначально написал о потере спортивного интереса в конце соревнования. Понятно, что 8 из 13 уж никак его не добавит. Может только в борьбе за самый топ, но, например, если речь идет о выходе в онсайт, то это правило будет крайне странным.
Вообще, предстаьте себе Формулу-1 и Феттеля, который последние этапы едет на Жигулях, помахивая рукой зрителям :)
Ну здесь конфликтуют несколько интересов: 1) участники, у которых много свободного времени, хотят как можно больше этапов. 2) участники, у которых мало свободного времени (например Petr team), хотят, чтобы у них был шанс побороться за победу, участвуя примерно раз в 3 недели. 3) философски хочется, чтобы была интрига до последнего этапа.
Я не вижу решения, которое удовлетворяет свойствам 1-3, поэтому предлагаю то, которое удовлетворяет 1 и 2. Что произойдёт со свойством 3 — сказать сложно. Может быть, интриги в конце как раз будет больше, потому что мы сможем пропускать этапы по ходу, отдохнём, а в конце как раз спортивный азарт возьмёт верх.
Два сезона 7+7 удовлетворяет свойству 1, но не удовлетворяет 2 (потому что этапов и зачетных этапов по-прежнему много) и, как следствие, свойству 3 (потому что у команд, у которых мало свободного времени, меньше мотивации бороться, когда это требует участия каждую неделю).
C, F, I?
I: Drawing some cases you can notice that no car need to go back ever because of two-lane first and last segments. The most effective way to avoid accident is always such: one of the car need to stop in the last but one (in its direction) X-coordinate of two-lane segment before the accident place, after stop it waits a moment when another car "touch" it (look at first case on the second picture in statement) and starts moving. Also you can notice that R doesn't influence to anything, so you can ignore it. So, we have some states (maybe more — depends on implementation): 1) first car is in A-point and second car somewhere at the road, 2) second car is in B-point and first car somwhere at the road. Moving from one state to another is simple — O(log(L)). Number of states is not big and you can easily find (using simple modelling) result for period from zero-time till the time some state firstly occured. When some state occured for the second time — it's a cycle. You just need to find number of cycle repeat and to do a modelling for remaing time. Complexity: O(cycle_length * log(L)).