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

Автор doreshnikov, 5 лет назад, По-русски

1547A - Кратчайший путь с препятствием

Идея: MikeMirzayanov

Разбор
Решение

1547B - Алфавитные строки

Идея: MikeMirzayanov

Разбор
Решение

1547C - Парное программирование

Идея: geranazavr555, MikeMirzayanov

Разбор
Решение

1547D - Взаимнорастущая последовательность

Идея: doreshnikov

Разбор
Решение

1547E - Кондиционеры

Идея: geranazavr555, MikeMirzayanov

Разбор
Решение

1547F - Стабилизируй массив (НОД-версия)

Идея: doreshnikov

Разбор
Решение

1547G - Сколько путей?

Идея: MikeMirzayanov

Разбор
Решение
Разбор задач Codeforces Round 731 (Div. 3)
  • Проголосовать: нравится
  • +228
  • Проголосовать: не нравится

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Wow! Hot solutions!

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +25 Проголосовать: не нравится

E was a wonderful problem to solve, love it!

  • »
    »
    5 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    Can u explain e?

    • »
      »
      »
      5 лет назад, скрыть # ^ |
      Rev. 2  
      Проголосовать: нравится +4 Проголосовать: не нравится

      My solution differs from the editorial.

      Let's start with the following idea: if we shift a cell righter by 1, we get closer to the conditioners on the right side and get further from the conditioners on the left side.

      What this means is that we can precount the values for the very first cell with the given formula, and then we will have to see where do the air conditioners belong for the current cell, either on the right side or the left one, and change their current distance by the same value.

      I hope you're familiar with priority queues or at least sets, where we will keep pairs of values: the first will be the temperature value(not the initial one, but the one we've precounted with the formula for the first cell) and the second will be the position of the air conditioner on the line; this will give us the minimum value instantly.

      We will have to use two sets: one is for the left side, the other is for the right side. At first, all the conditioners obviously belong on the right side, so you should fill the right set.

      The loop from 0 to n — 1 is where the magic happens. We should take the minimum conditioner off top the right set and see if it is an impostor and should have been already swapped to the left side, because its position is smaller than the position for our current cell; if it has to be swapped to the left side, then we should delete it from the right set, update the temperature value for its pair, which will become its initial value + 1 — i, and insert that to the left set(if you're struggling with how to get the initial value, you can use map, where the key would be the conditioner's position and the value would be the index in the array of initial values). After we've done that, we can be sure that the conditioners do belong to the right sets.

      As we've assumed that we get closer to the right conditioners and further from the left ones, this means that we can find the minimum value as

      min((*left_side.begin()).second + i, (*right_side.begin()).second - i);
      

      This would give us the complexity of O(n + k * log(k)). Here's my solution with priority queues.

      I probably explained it badly, you might also want to see Colin Galen's solution(1:42:52), which is the same as in the editorial and is quite good.

      • »
        »
        »
        »
        5 лет назад, скрыть # ^ |
        Rev. 2  
        Проголосовать: нравится 0 Проголосовать: не нравится

        Hello, I think I came up an idea like you after the contest end. But my code got TLE. Can you take a look? 122107507

        • »
          »
          »
          »
          »
          5 лет назад, скрыть # ^ |
           
          Проголосовать: нравится +15 Проголосовать: не нравится

          Fixed: 122137899

          1. You probably messed up with a formula a bit. I'm not saying it is incorrect because it was rather hard to understand the logic behind (n — i), but using just plain -i and +i looks easier for me.
          2. You don't check whether tmp1 does actually exist, i.e tmp1 != a.end(). Therefore *tmp1 is the reason of your TLE.
          3. You do the lower_bound() through the array a, but have you sorted it previously? Its elements can be a total mess and the function would return random stuff depending on the order of the input elements(we're not guaranteed that the input is sorted).
»
5 лет назад, скрыть # |
 
Проголосовать: нравится +54 Проголосовать: не нравится

F and G were absolute gold. Thanks for the set!

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +78 Проголосовать: не нравится

The number of accepted solutions increased gradual way.

Proves that Level of question increased in a very uniform way. Loved this !!!

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +8 Проголосовать: не нравится

Fast editorial!

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Wow, I really liked this contest, not just because I am expected to gain 127 points.

A -> well, it's problem A.

B -> nice, introductory 2 pointer

C -> this took me a while because I was chasing down the wrong rabbithole

D -> interesting bit problem

E -> nice, but easy, problem

F -> nice segment tree

G -> couldn't solve

  • »
    »
    5 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    Can you explain how to solve F using segment tree

    • »
      »
      »
      5 лет назад, скрыть # ^ |
      Rev. 4  
      Проголосовать: нравится +32 Проголосовать: не нравится

      Let's imagine our array in stages. For convenience, I duplicated my array just to deal with the cyclic nature of the problem.

      $$$a_1, a_2, a_3, \dots a_n$$$

      $$$\gcd(a_1,a_2), \gcd(a_2, a_3), \dots \gcd(a_n, a_{n + 1} )$$$

      $$$\gcd(a_1,a_2, a_3), \gcd(a_2, a_3, a_4), \dots \gcd(a_n, a_{n + 1}, a_{n + 2})$$$

      etc

      So let's binary search on the answer. Say, we are wondering if the answer of 3 is possible. Then, we want to ensure that $$$\gcd(a_1,a_2, a_3) = \gcd(a_2, a_3, a_4) = \dots = \gcd(a_n, a_{n + 1}, a_{n + 2})$$$. We can check this using a segment tree with range gcd queries. Since we do a binary search, we have a final of $$$\mathcal{O}(N \log N \log N \log (\max(A_i ))$$$

      Solution
  • »
    »
    5 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +20 Проголосовать: не нравится

    My solution to G.

    You can do a basic DFS to find if the answer is 0 or 1 or 2 for every component.

    Use Tarjan's SCC algorithm to find all strongly connected components. Do a multisourced BFS from every SCC reachable from 1. Every node reachable by this BFS is a -1.

    This solution works in O(N).

  • »
    »
    5 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    how do you predict your rating change?

»
5 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

Please, fix the code of F.
Fix this line: const unsigned int MAX_A = 1000'000;

Thank you for D, E and F. Didn't see G.

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +9 Проголосовать: не нравится

Maybe it is just me who came up with bad solutions (dp for C, dijkstra for E, bfs-based toposort for G), but the implementation was quite painful for most of the problems today. Not something worth coming to Codeforces for :c

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +6 Проголосовать: не нравится

Just to confirm, for F, using Sparse Table shouldn't TLE right?

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

This round made me want to commit not alive

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Almost greedyforces, upto E. F was a nice problem.

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

At the end of time I just know how to solve it but too late. Anyway I thing F is great. Great contest. Love!

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +4 Проголосовать: не нравится

I used some kind of Dijkstra Algorithm (multi source) to solve E

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +44 Проголосовать: не нравится

During the contest, I think problem G is a wonderful problem since it's exactly a proper problem for those who just learn strongly connected components to practise.

However, seeing the editorial, I think the G is more wonderful than I have thinked.

»
5 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится -10 Проголосовать: не нравится

please, somebody, tell me... why my solution is wrong for problem B and which test cases it is failing... 121938514

there is a minute error... i.g. some very minute error is present... it failed the 5002nd case which is not visible.

  • »
    »
    5 лет назад, скрыть # ^ |
    Rev. 2  
    Проголосовать: нравится +1 Проголосовать: не нравится

    The error seems to come on the string "abcdefghijklmnopqrstuvwxyz", your code gives No as output. I checked your code and it's because of the array declaration int alphabets[25], it should have a size of 26 not 25.

    • »
      »
      »
      5 лет назад, скрыть # ^ |
      Rev. 2  
      Проголосовать: нравится -41 Проголосовать: не нравится

      checked this for my code ... It is giving correct output

      • »
        »
        »
        »
        5 лет назад, скрыть # ^ |
        Rev. 3  
        Проголосовать: нравится +2 Проголосовать: не нравится

        First, completely unecessary to call him a dickhead for helping you.

        Second, you are wrong. In your computer it works because even though you are accessing a higher index than you allocated it doesn't give an error, which can happen sometimes when you're in your local computer, but it will give an error on codeforces and can give an error on some other computer (like brobat's).

        The worst part is that that's not the only reason why the code is wrong because you got wrong answer instead of runtime error, so your idea is also wrong

        • »
          »
          »
          »
          »
          5 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится

          That's not necessary that the idea is wrong, accessing elements out of array bounds can return unexpected values and not RE — and that can cause WA.

          • »
            »
            »
            »
            »
            »
            5 лет назад, скрыть # ^ |
             
            Проголосовать: нравится +1 Проголосовать: не нравится

            As far as i know, in codeforces they actually go out of their way to check if you're accessing the array in bounds and not only give you a runtime error but they also highlight the line where this is happening.

            And the idea is wrong, they check where 'a' is and sees if the values increase as they go to the sides. This is not sufficient as "zax" would work but isn't actually a valid string. Also i believe the array they use to track frequencies can hold garbage data but im not sure

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

I used binary search+ sliding window(with map/unordered_map) but why this code is giving TLE? complexity seems like O(n*factors[a[i]]*log(n*fact[a[i]]) (including map factor)

[submission:link]

»
5 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +2 Проголосовать: не нравится

There is no need to find the position of 'a' in problem B, we can start checking the values from endpoints of string as well...

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

I think I have a very easy to understand solution for E: https://mirror.codeforces.com/contest/1547/submission/122007085

Iterate over conditioners, and for each go left and right, while you can cool down cells, it gives you O(n+k).

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Awesome contest. Where can I find more problems similar to D?

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

I was able to do A,C,D. But I got WA for B. I don't know where I did a mistake.Every test case I tried randomly seems to be fine.

Can someone plz help me with it?

https://mirror.codeforces.com/contest/1547/submission/121969497

  • »
    »
    5 лет назад, скрыть # ^ |
    Rev. 2  
    Проголосовать: нравится -9 Проголосовать: не нравится

    The same happened to me, dude... I don't know where's the problem... you help me please 121938514 this is my solution... please please help me as soon as you get it

  • »
    »
    5 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    i think you just read the problem wrong because i have no idea of what you're checking. Could you elaborate on your idea?

    • »
      »
      »
      5 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится

      First I'm checking for duplicates and any alphabet whose value is greater than length of string(considering a's value to be 1.If string length is 3 only a,b,c can be there.) and storing the positions of characters.

      Now as we build from lowest alphabet, each character can go to right or left of string,i.e it can just be beside previous character or at other extreme(so the gap between to consecutive alphabets would be equal to all the previous letters before these 2 consecutive ones).( abs(mp[i]-mp[i-1])==1 || abs(mp[i]-mp[i-1])==i)

      As we're building and checking the gap from lowest pair of consecutive alphabets ,if for all alphabets until length of string ,every condition satisfies then it would be alphabetical string.

      Hope this helps :)

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +8 Проголосовать: не нравится

Test Cases separated by a line helped a lot while debugging. Please continue doing so.

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +10 Проголосовать: не нравится

Pizzeria Queries sends its regards.

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

I used priority queue to solve E.121971913

»
5 лет назад, скрыть # |
Rev. 3  
Проголосовать: нравится +4 Проголосовать: не нравится

Am I the only one who used the minimum on the queue to solve the problem F? 121980439

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

My own solutions for B, C and E:

B. If we reverse the operations, we'll need to remove letters from the beginning or from the end of the given string. Two pointers (L and R) showed the part of the string that is not removed yet. So I iterated on letters from 'a'+s.length()-1 to 'a' and shifted one of the pointers. That allows to solve this task in O(n), not O(n^2) as in editorial.

C. On each turn, we can take the minimum of a[i] and b[j] — if it's invalid, the other value is invalid as well. So, checks with a[i] == 0 and b[j] == 0 are not needed.

E. Tried to add only "effective" conditioners — conditioners which cool some cells. I sorted the given conditioners by increase of their temperature and iterated over them, checking if some conditioners could be skipped. Then, the answer is affected only with conditioners near the cell (the nearest on left side and the nearest on right side).

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

121992524

Please provide some hint on where this solution seems to be incorrect.

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

it was a realy good contest thanks for all setters and testers for make beautiful contest

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

D was the best and I really liked it =)

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Problem: 1547F - Array Stabilization (GCD version) can be solved using two pointers stack trick, which can be learned through EDU "Two Pointer" section. Link: https://mirror.codeforces.com/edu/course/2/lesson/9/2, video is called "Segment with Small Spread", my solution: 122018965

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +4 Проголосовать: не нравится

Problem E was really interesting!

But I think, there is a small mistake in Editorial. In my opinion, it should be $$$L_{i}=min(L_{i-1}+1,c_{i})$$$ instead of $$$L_{i}=min(L_{i+1}+1,c_{i})$$$

Thanks for contest again!

»
5 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

For problem D, there is a solution using greedy with less thinking, but with a little worse time complexity.

If we treat every integer as a 29 bits binary numbers. To make $$$y$$$ lexicographically minimal, start scan the sequence from position 1, and each time try make $$$y_i$$$ as minimum as possible.

First of all, $$$y_1 = 0$$$.

And then for $$$i \gt 1$$$, we can let $$$y_i = g(x_i)$$$ first, where $$$g(x_i)$$$ is bitwise-not of $$$x_i$$$. Since by doing this, $$$x_i \oplus y_i$$$ will be all 1's, and this must satisfy the requirement of growing.

After this, we can enumerate every 1 in $$$y_i$$$ from higer position, and change every 1 to 0 if possible.

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

in problem G, one of the test cases is:

3 2 3 3 2 2

my answer was 1 0 0 expected answer: 1 -1 -1

acc to me, there ate 0 ways to go from vertex 1 to vertex 2 or 3. but expected answer was that there are infinite solutions. Am i missing something? My Solution link

»
5 лет назад, скрыть # |
Rev. 4  
Проголосовать: нравится 0 Проголосовать: не нравится

Problem E was easier than I thought...

My solution was different, involving Segment Trees (This is an overkill, btw).

I had solved a kind-of-similar problem on CSES. The problem: Pizzeria Queries

The major difference being that there were updates in that problem. However, I went ahead and coded up that solution during the contest. After the contest did I realise how simple and elegant the code for E was.

Anyways, incase someone is interested in the code: 121978627

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Can someone look at this solution for E. I used bfs for it, but for some reason I got TLE on test 12. Can someone spot a mistake that causes an infinite loop, because it should run in O(n)

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

F is heck of a problem!!!✨

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Hmmm!

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

A bit different approach to problem F:

Notice, that the number of times a[i] changes is small (worst case is log(a[i]), I believe). So if we can do a brute-force solution where we only change the elements that need to be changed, we can get N*log(MaxValue) complexity.

Note, that a[i] changes only if it's not a divisor of a[i+1]. Let's keep track of segments of elements where $$$a[l] \mathrel{\vdots} a[l+1] \mathrel{\vdots} ... \mathrel{\vdots} a[r]$$$. Only the last element may change after one iteration. It's also pretty straightforward to update the segments after the iteration as well.

Code: 122069028 ( I used std::set here, so the complexity is not optimal, you can rewrite it using std::vector).

»
5 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

If you're interested in a video, I explained all the problems on stream, and you can watch at https://youtu.be/QKW3_9RFxDI

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

is it possible to do binary search on the F sum? like by taking x over 0 to n steps ?

  • »
    »
    5 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    Yeah, you can binary search on the number of operations. Basically, at $$$k$$$ th step $$$a_i$$$ becomes $$$gcd(a_i, ... , a_{(i+k)\%n})$$$. And to calculate gcd fast, you can use binary lifting. Look at my solution 121972800. This is $$$\mathcal{O}(n\cdot log^2 n)$$$ but you can make it faster by combining binary lifting and binary search. Similar to the idea mentioned here.

»
5 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

Problem E was great. Can Problem E be solved using priority_queue ?

»
5 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

We can do Problem F using segment tree and binary search.

Firstly the final value of array when they are equal will be gcd of entire array which has been explained in tutorial, let this value be GCD.

Then we will form a segment tree where:

tree [node] = gcd (tree [ left_Child ], tree [ right_Child ] )

Finally binary search on number of steps required, for any number of steps x we will check for each ith index(0<=i<n) in array if

gcd(arr[i] % n, arr[i + x] % n) == GCD.

For more clarity check out my submission 126403245

»
4 года назад, скрыть # |
Rev. 3  
Проголосовать: нравится 0 Проголосовать: не нравится

148276776 Can anyone please explain, why it is giving WA on test-2?