Привет, Codeforces!
В среду, 10 июня 2020 г. в 17:35 (UTC + 3) состоится End of the learning — Beginning of the tour contest (Div 3).
Это мой первый раунд (мэшап, так как даже для тренировок рейтинга нет, потому что надо прекращать писать контесты с телефона) с полностью моими задачами. Соревнование будет проводиться по правилам ICPC. По стандарту, штраф за каждую неверную посылку до посылки, являющейся полным решением, равен 20 минутам. За 20 минут до конца контеста таблица будет заморожена.
Вам будет предложено 6 задач на 2 часа. Я надеюсь, что они покажутся интересными для вас. Особые надежды возлагаю на задачу E. Как по мне — это самая интересная из них.
Задачи вместе со мной тестировали Ahmad Ahmadsm2005 Said, Ahmed ahmedfouadnew Fouad, Матвей Irpacci Кулинич и Максим Xennon Карпук. Также большое спасибо Михаилу MikeMirzayanov Мирзаянову за системы Polygon и Codeforces!
Удачи в раунде! Успешных решений!
И чуть не забыл, вот ссылка:
https://codeforces.net/contestInvitation/4036ec99932a47484351d57a812de34c7a4fbb2c
Good luck!
Thank u very much!
А $$$5 \times 3$$$ можно? А если я сделаю список массивов размера 5, размеры массивов соответственно 5, 4, 3, 2, 1? А если я сделаю трехмерный массив размера $$$3 \times 3 \times 3$$$? А одномерный размера $$$10^6$$$ можно? А если я сделал таблицу $$$4 \times 4$$$, содержащую в себе
long long
, но из-за особенностей хранения типа могу использовать ее как таблицу $$$4 \times 8$$$, содержащуюint
или $$$4 \times 32$$$, содержащуюchar
? Можно поподробнее, чего нельзя делать, а то у меня еще парочка идей есть.В целом такая идея мне видится очень плохой, лучше ее все-таки как-то избежать. Может быть, если сделать задачу интерактивной, получится убрать эту ручную проверку?
Я тут немного подумал, разобрался. Там скорее всего я сделаю ans % (1e9+7)
Всё, таска готова! Удачи на контесте!
Из-за первого вопроса, я подумал, что контест уже прошел и я профукал его. Не пугай так больше!
хахаха)
Is the time UTC+9?
UTC+3
Чтобы писать красиво $$$10^5$$$ достаточно написать такое выражение между долларами:
$$$10^5$$$
(я не знаю, почему доллар заменяется на три доллара, администрация сайта меня по этому вопросу игнорирует)Ок, буду иметь ввиду на следующих контестах. Спасибо большое!
Isn't the penalty set to 20 minutes (in the contest)?
why?
I'm not saying that it should be, I'm saying that it is, even though you mention the penalty is 10 minutes.
For example, see my score: (if it's blurry, https://imgur.com/a/JpaNEYU)
My solve times are 1 + 3 + 5 + 7 + 13 + 18 = 47, meaning that my 3 penalties are each causing 20, not 10 as they should.
It may be. I will correct it in blog
Первый контест от l-_-l был лучше
Кому как. Я же ещё во время составления и экзамены писал
How to solve F?
I will public solves later
Кто пишет на С++ и получил по задаче А вердикт "Неправильный ответ на тесте 15" — попробуйте отослать без функции
trunc()
.Или (int)trunk(a/b), потому что нужно вывести целое число, а trunk() возвращает double
А кто пишет на питоне — пишите на плюсах, а то взятие по модулю работает не так) Вообще такая задачка хорошо проверяет навыки проблемсеттинга)
Спасибо большое! Только я не пойму: это хорошо или плохо?
Просто стоит это писать в условии. Думаю, что если бы все числа были положительные, то задача бы только выиграла от этого.
Хорошо, что есть про использование trunc() — это определяет округление отрицательных чисел, которое тоже не очень очевидно само по себе.
Меня еще поначалу смутило, что числа до $$$10^{18}$$$, а запрашивается их произведение. Решил написать на питоне, чтобы не заморачиваться в int128, ну и столкнулся с этой проблемой) А потом вообще оказалось, что тесты слабые и такого не происходит)
Я кстати тоже удивился насчёт тестов. Я похоже при тестировании задачи в генераторе поставил 1е9, а потом забыл вернуть)
Но генератор на testlib — классная штука!
А будет письменный разбор задач, с доказательствами, наблюдениями и т.д?
Да. Я сейчас немного занят, поэтому позже я его опубликую
try_kuhn, is it okay if I post a brief editorial here for everyone (since submissions are public now)?
Okay, I will do it too) there would be 2 editorials)
Slight editorial (with author permission):
This is mostly about knowing how your language works. Division, however, gets picky. It's a good idea to not use doubles because they have precision issues (read). Instead, you can use integer division, which automatically truncates (in C++, at least), possibly having to be careful with negatives in other languages.
For the actual implementation, it seems like the test cases are designed so overflow won't happen and you won't have to mod with negative numbers, so the rest is simple.
My submission: [submission:83308763]
Consider all numbers that have to be odd. Because numbers are nonnegative, each odd number must be worth at least $$$1$$$. Similarly, each even number must be worth at least $$$0$$$. So the minimum possible number you can create is $$$c_o$$$ — the number of required odd numbers. You can create any $$$s \geq c_o$$$ where $$$s$$$ and $$$c_o$$$ have the same parity (just add $$$2$$$ until you get there), and you can't create any $$$s$$$ of different parity. So the final conditions to check are that $$$s \geq c_o$$$ and $$$s \mod 2 = c_o \mod 2$$$.
My submission: [submission:83309018]
Store any form of set (
std::map
in C++,java.util.TreeSet
in Java, a dictionary in Python, I don't know about other languages) that supports fast insertion and checking if an element is in the set. Then the first type of query is insertion, and the second type of query is checking if an element is in the set, which is perfect.My submission: [submission:83309210]
This is a direct application of segment trees. I... don't have more to say about this one.
My submission: [submission:83309468]
This is a problem with a simple solution, but one that may be hard to come up with.
First, we must note that this problem is exactly equivalent to finding the number of paths from $$$(1, 1)$$$ to $$$(i, j)$$$ in a rectangular grid, where you can only move down or right (read). Why is this so? It's given in the statement that each value at $$$(i, 1)$$$ and $$$(1, j)$$$ is $$$1$$$. Conveniently, there's always exactly $$$1$$$ path to each of these cells. For all other cells, to get to $$$(i, j)$$$ (in the path problem) there are two places you can come from — either $$$(i - 1, j)$$$ or $$$(i, j - 1)$$$. Thus the number of ways to get to $$$(i, j)$$$ is the sum of the number of ways to get to the two places you can come from.
This gives us a dynamic programming recurrence: $$$dp[i][j] = dp[i - 1][j] + dp[i][j - 1]$$$ where $$$dp[i][j]$$$ is the number of ways to get to $$$(i, j)$$$. Note that this is exactly the same as the one given in the problem.
Now that we've reduced the problem, let's attack the path problem a bit harder. Currently, our solution is $$$O(i \cdot j)$$$, which will certainly not pass. Let's think of the path from $$$(1, 1)$$$ to $$$(i, j)$$$ as a string of the moves we make:
D
for down andR
for right. This string must be of length $$$(i - 1) + (j - 1) = i + j - 2$$$, have exactly $$$i - 1$$$ ofD
, and exactly $$$j - 1$$$ ofR
. And our goal is now to count the number of different strings. A bit of combinatorics tells us that there are exactly $$$\dbinom{i + j - 2}{i - 1}$$$ or $$$\dbinom{i + j - 2}{j - 1}$$$ possible strings.Now we just have to compute the answers under the tight memory conditions. $$$\dbinom{i + j - 2}{i - 1}$$$ is equal to $$$\dfrac{(i + j - 2)!}{(i - 1)!(i + j - 2 - (i - 1))!} = \dfrac{(i + j - 2)!}{(i - 1)!(j - 1)!}$$$. Computing factorials and inverse factorials can be done iteratively with $$$O(1)$$$ space and $$$O(i + j)$$$ time (although $$$O((i + j)\log{(10^9 + 7)})$$$ time is simpler).
My submission: [submission:83310114]
We can maintain the probability of ending in each tunnel iteratively. Let $$$a_i$$$ be the given probabilities for each turn $$$i$$$ from the input, and $$$p_i$$$ be the probability of ending at tunnel $$$i$$$ (for $$$i$$$ from $$$1$$$ to $$$n + 1$$$). Then $$$p_1$$$ is just $$$a_1$$$ because we have exactly that chance of ending in that tunnel. Otherwise, we have a $$$100 - a_1$$$ chance of advancing to tunnel $$$2$$$. Then, at tunnel $$$2$$$ we have a $$$(100 - a_1)a_2$$$ chance of stopping in tunnel $$$2$$$, and a $$$(100 - a_1)(100 - a_2)$$$ chance of advancing to tunnel $$$3$$$. More generally, the probability of stopping at tunnel $$$i$$$ is $$$p_i = (100 - a_1)(100 - a_2) \dots (100 - a_{i - 1})a_i = a_i \cdot \prod\limits_{k = 1}^{i - 1}(100 - a_k)$$$, where $$$a_{n + 1}$$$ is just $$$1$$$ because we have to stop there.
The final answer is then just the expected value, which is $$$\sum\limits_{k = 1}^{n + 1} k \cdot p_k$$$. Be careful with output (use
setprecision
with a large number of digits in C++) to make sure the jury knows your answer is correct because small-number accuracy is important here.My submission: [submission:83310636]
Hello! How you did these opening triangles?
These are spoilers:
Ok! Thank u very much!
You can public it in your blog, I will add link
I will do editorial on russian lenguage then
For F when you turn right you go to another tunnel.So for p1 shoudn't it be 100-a1 for ending in that tunnel and then advancing for 2nd tunnel you should have a1 chance for that ? Or I have misunderstood the question
The statement's not the clearest, but I interpreted "turn right" from
On every turn person can turn right with probability a [i]
as "end at that tunnel with probability $$$a_i$$$" and "go straight" as "continue to the next tunnel"Yes, you're right!
"the tunnel with n turns, which lead right, in other tunnels" This statement made me think you have to turn right to go to another tunnel
I won't do such mistakes later
Why did you took the path from (1,1) to (i,j) ?I mean what's the reason or intuition behind this.Thanks in advance
Unfortunately, there isn't much intuition. The best I can say is "I've seen this problem before, so I recognized it quickly."
Thanks for the contest! Looking for more contest like this one.
Thank u very much! I will do new later!
I think you meant editorial here too instead of parse.
Yes
Done!
Some suggestions:
Try to use MathJax format. For example, something like
1<=n<=1e5
should be$$$1 \le n \le 10^5$$$
(use single dollar sign, but not 3 dollar signs) which will be displayed as $$$1 \le n \le 10^5$$$Try to spell key words correctly. ( guaranteed but not garanted)
Hope you can make better contests next time :D
Thank u very much!