Hi everybody!
I'm glad to invite you to the Yandex Algorithm Round 2 that will happen tomorrow at 21:00 Moscow Time. This round is prepared by me with a great help of GlebsHP. I want to say thanks to Chmel_Tolstiy, snarknews and Gassa for their support during the preparation and to all of the Yandex developers that tested this round.
Good luck and have fun!
Link to the contest will be posted here as soon as I manage to find it by myself :)
UPD: the link to the contest is located here: https://contest.yandex.com/algorithm2016/contest/2540/enter/
UPD2: Thanks everybody for the participation, I hope you enjoyed the round! Results will be available shortly. I'd like to publish an editorial, but it fails to compile on Codeforces and I'm trying to fix this issue.
UPD3: Congratulations to winners:
The preliminary pdf-version of an editorial is posted: http://codeforces.me/blog/entry/45354. Continuing the nice tradition of providing an editorial with questions related to the problems, I invite you to think about them/
There is no way to participate for those who didn't took part in previous rounds, am I right?:(
Unfortunately there is no way to participate during the contest for those who didn't qualified.
Though after each round is held, it becomes available for participation on http://contest.yandex.ru. We will also, most probably, publish archives containing test data and all materials of all rounds in the nearest future.
Why is there no mirrors on CF? I don't know how difficult to make mirror but think it should be simpler than make new round from scratch (in this case CF get all problems for free).
Darn, it overlaps with first match of Euro : /.
Yep, I'm choosing a nice bar with live football to conduct the contest from there right now :)
Sorry for that, I couldn't do anything with the time of round.
I can send you messages about goals via testing system :D
At least we will be able to watch second half. What is worse is that DCJ overlaps with first match of Poland ;__; (also first half)!
Easy, just quickly solve all problems.
Easy, when you know how.
Thank for sending me notifications about all of the goals ;).
I had an opened tab with text footage of the match but they didn't give me an option :)
Don't forget to participate!
Была ли регистрация к раунду ? Было бы лучше если её открыли во время контеста.
Её не было и не будет. Регистрация была на участие в квалификационных раундах, которые уже прошли.
Thanks for making the system fast and stable this time. :)
How to solve C?
I used bruteforce. Code.
Notice that for integer a number of used banknotes is
(all divisions are done in integers).
It can be rewritten as
So we need to maximize the subtrahend
This can be done with DP.
Code.
Well... it is kind of the backwards sieve of Eratosthenes, isn't it?
An N log N DP solution:
We'll pick coins from smaller to bigger. Suppose we already picked some coins and the biggest of them is A. We used coins <A to make all prices divisible by A. dp[A] is the minimum number of coins used to do so. dp[A*k]=min(dp[A*k],dp[A]+sum(price[i]/A%k)).
6 years ago I wrote the same problem: https://community.topcoder.com/stat?c=problem_statement&pm=10569
Yes, d1 med was easier at that time.
Ouch : \
It's funny that I wasn't able to solve the problem back then, but it was a piece of cake today (I didn't remember it at all).
The other way around would be funny ;)
http://petr-mitrichev.blogspot.com/2015/10/a-week-with-old-self.html
I solved it 6 years ago, but WA today... (somehow I thought k and n are the same variable)
BTW, consider the other version of the problem I've came up with before this one. It is formulated in my editorial. Are you able to solve it efficiently?
How to solve B?
Write L and R in binary form.
Now the problem can be solved independently for each bit: you need to calculate for each bit how much there will be nums in [l, r] with this bit set and unset. And then select the bit value, based on this info.
How to count how much nums in [l, r] with such bit set? Traditional trick: it is count in [0, r] — count in [0, L — 1].
So how much nums in [0, r] with i'th bit set? let r = A C B (where A value of highest bits, c value of i's bit, B value of lower bits) It is A * 2^i + c * (B + 1).
(At first consider all numbers which are less than A * 2^(i + 1), and then the all other)
In first group exactly half will be good, and in second none will be good if i'th bit unset (c == 0), and all numbers in [A C {zeros}; A C B] otherwise.
How did you calculate the number of nums in [L, R] with this bit set and unset?
I've written second part and updated comment.
I dont know how he did it, but I think it can be done easily using DP on digits with state DP(bit, lower, larger, tofix) which is O(323·2·2·) where bit is the bit we are currently on, lower is {0, 1} denoting whether any previous bit is lesser than the bit in R, and larger is {0, 1} denoting whether some bit has been strictly larger than that of L. tofix denotes the bit we are fixing to be true. After that, it can be solved by using a lot of if-elses. I couldn't get it accepted in contest(WA on #10), but I dont think the DP would be wrong. My transition probably has bugs :/
Is there anything wrong with this approach?
UPD: Damn, extremely overkill :/
Got this strategy but couldn't count how many times it occurs. Can you explain you method to count how many times each bit is set in range [l,r].
For Problem B, finding the number of integers in [L, R] with ith bit set could be used to decide if the required number should have ith bit set or not, to minimize the hamming distance.
So, how do we find number of integers in [L, R] with ith bit set?
Find count of '1' for every position for all numbers from 0 to n;
It's linear in number of digits.
Then you can do F(r) — F(l-1) to find what you need.
We can calculate the number of integers in [0, R] with i-th bit set using the following fact: if we consider consecutive blocks of size 2i + 1, the first half of integers has i-th bit set to zero, and the second half with i-th bit set to one. Therefore, one can come up with simple formula.
That awkward moment when your solution to D fails because of
That awkward moment when the bug in your code is that you forget to return your answer...
an awkward moment when you haven't finished reading A, wrote solution in 5:24, sent it blindly and it obviously failed because it never outputs -1 xD
That's why keep warnings flag on always, same thing happened with me 1 year ago and your's is still int returning function mine was bool returning which doesn't show warning also.
Thanks for the tip.
How to solve D?
ans(C) = ans(C - A) + ans(C - B), ans(0) = 1 and use fast matrix exponentation.
Sum of required f(x,y) is sum of f(x-1,y)+f(x,y-1)
if Ax+By=C, then A(x-1)+By=C-A, Ax+B(y-1)=C-B
so you need to calculate answers for C-A and C-B and sum them
the rest is converting linear recursion to matrix powers
Thanks a lot! It was simple but i turned it into a complicated series of binomial coefficients and could not simplify it :(
Good interesting problems, thanks for the round!
Is there a simple approach for problem E? I have several overcomplicated in mind, however wasn't brave enough to implement any of them.
First, you need to compute, for each vertex, how many vertices with a higher number are there in its subtree (nIni), in each of its childen's subtrees (nChildij), and outside of its subtree (nOuti).
To compute the numbers, first sort the vertices in the order of preorder traversal. Each subtree will be represented by a contiguous interval in this order. Create a Fenwick tree. Process vertices in the order of assigned numbers, and use position in preorder traversal as an index in the Fenwick tree. Then, you will be able to compute how many already processed vertices are in any given subtree in .
Then, you can move the root along edges and maintain current number of inversions in O(1) time for each move. Let's call "current root" the vertex you are currently computing the answer for, and "initial root" is the vertex that you used as a root in the previous steps. The answer can be computed as the sum of contributions of each vertex, where contribution of vertex i is defined as:
As you may see, when moving the current root along an edge, only contributions of two vertices may change (ends of that edge). So, the answer can be updated in O(1). Since it is possible to visit all vertices using O(n) such moves, this part takes O(n) time, and the entire solution takes time.
Last round I was afraid to submit anything blindly and because of that I was a victim of wrong tests in C. This round I thought I need to risk ans submit something blindly, so since I was pretty sure of D (it can't not work if it works on samples, right?), so I submitted it blindly and it turned out to be only one of my submissions that wasn't right :|. a=b case xd.
How to solve F?
I've just posted a PDF-version of an editorial: https://yadi.sk/i/1hC1divYsQtTQ
Has somebody encountered WA #18 in problem D? I have no idea what's wrong with my code (linear recurrence -> fast matrix exponentiation).
It is said in the editorial that A = B in that test.
Well, there are smaller tests with the same condition (for example A = B = 100 in test #10), and I did
so it's something different I guess.
Ooops, WA #18 checks int overflow (C >= 2^31). I feel stupid right now. =)
Are there any chances for me to get a T-shirt if I missed Yandex Algorithm Round 2?
If you get to the top 512 competitors — yes, sure. You can track your position here.
How to solve E that fast? I create some BSTs and "merge" them in some way to count the inversion, which leads to an O(n log^2 n) solution. My code is a little bit complicated so I wonder if there's a better solution...
Edit: Well I just saw the editorial. It seems not easy to implement though...
Edit: I saw tonynater's code. Now I know how to solve it :P