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

Автор awoo, история, 3 года назад, По-русски

1569A - Сбалансированная подстрока

Идея: BledDest

Разбор
Решение (awoo)

1569B - Шахматный турнир

Идея: BledDest

Разбор
Решение (Neon)

1569C - Заседание жюри

Идея: BledDest

Разбор
Решение (Neon)

1569D - Неудачные пары

Идея: BledDest

Разбор
Решение (adedalic)

1569E - Восстановление турнирной таблицы

Идея: BledDest

Разбор
Решение (BledDest)

1569F - Палиндромный гамильтонов путь

Идея: BledDest

Разбор
Решение (awoo)
  • Проголосовать: нравится
  • +108
  • Проголосовать: не нравится

»
3 года назад, # |
  Проголосовать: нравится -48 Проголосовать: не нравится

Fastest editorial I've seen

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

Lesson learned: Don't use segment trees unless required.

(My segment tree implementation for D gave TLE on system testing.)

»
3 года назад, # |
  Проголосовать: нравится -7 Проголосовать: не нравится

code and explanation for problem D

Spoiler
»
3 года назад, # |
  Проголосовать: нравится -7 Проголосовать: не нравится

I am facing some difficulty in understanding the equation in Problem C: $$$A_n^{n-k-1} = \frac{n!}{(k+1)!}$$$ What is $$$A$$$ here and how did we get $$$\frac{n!}{(k+1)!}$$$?

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

    $$$A_x^y$$$ is the number of ordered ways to choose exactly $$$y$$$ different objects from $$$x$$$. So, it's like a binomial coefficient $$${x}\choose{y}$$$, but with also considering the order in which we choose the object. Hence the formula for $$$A_x^y$$$ is $$${{x}\choose{y}} \cdot y! = \frac{x!}{(x-y)!}$$$: there are $$${x}\choose{y}$$$ ways to choose exactly $$$y$$$ objects out of $$$x$$$, and $$$y!$$$ ways to order them.

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

      why to select n-k-1 from n we know which elements are n-k-1( n-k-1 elements are those which are not equal to ax or ax-1,where ax is the maximum element);

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

        It is like considering the positions; instead of the elements. There are in total n positions. We wish to pick n-k-1 positions among them for the n-k-1 elements. There will be k+1 gaps after that. The last gap is fixed for the max element. The rest of the k elements goes k! ways into the rest of k gaps. I was also confused at first. Hope this helps.

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

    nPr formula is n!/(n-r)! where nPr represents permutating r numbers in n places. It is basically n p (n-k-1).

»
3 года назад, # |
  Проголосовать: нравится -7 Проголосовать: не нравится

Problem C : if (cmx == 1) ans = (ans — sub + MOD) % MOD; I don't know why we need plus MOD. I thought we just need : ans = ( ans — sub ) % MOD Thanks for someone explain this (^^)

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

    It's because ans and sub are both %MOD, and if (ans%MOD — sub%MOD) < 0, so ( ans — sub ) % MOD will be < 0 too, that's because the % of negative numbers is also negative.

    for example, if MOD = 1e9+7, sub = 5 and ans = 1e9 + 8 (but in your code ans = 1, because you do ans%= MOD): ans = (1 — 5)%MOD = -4%MOD = -4

    But if you add MOD this never you be negative, because sub < MOD.

    I hope you understood and sorry for my bad english, I'm not fluent.

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

      I get that you are doing this because ans-sub can be negative but how does MOD+(ans-sub) give the right answer when ans-sub is negative. Is this a property of MOD?

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

        The "taking value modulo MOD" operation basically tells you the distance between your number and the previous number that divides MOD. So in case of negative numbers (in range (-MOD; 0)) you need to find the distance between -MOD and your number. If you shift both values by adding MOD it becomes the distance between 0 and (your number + MOD) which is of course (your number + MOD).

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится -7 Проголосовать: не нравится

    By the way, answer can be simplified to n! * k / (k+1). That way you don't need to subtract modulo MOD :)

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

In problem C my approach giving the wrong answer on test 2 but I couldn't understand why it is giving this error.

My Solution
Code

I tried to explain it well. I hope you got it and you can help me.

UPD: I added accepted solution so you can check my solution to understand the problem.

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

    It's because of this int x = (fact(n) / fact(mp[maxi] + mp[maxi-1])) % mod;

    fact(n) is divisible by fact(mp[maxi] + mp[maxi-1] if you don't use mod, but with mod it doesn't, for example:

    16 is divisible by 8 but if i use mod 3 (16%3 = 1 and 8%3 = 2): 1 isn't divisible by 2

    To fix this we can use module inverse, you can see it here or here

    I hope you understood and sorry for my bad english.

    upt: I don't know if the rest of your solution is correct

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

For problem A you can use two pointers.

Spoiler
  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится +23 Проголосовать: не нравится

    Is it worth ?

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

    There are 4 methods for this question. 1. O(n) — simple traversal as described in editorial. 2. O(n^2) — brute force — generating all subarrays 3. O(n) — using two pointers. 4. O(n) — using traversal + map used to store sum till particular index

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

      What about finding count of 'a' and 'b' for each range using segment/fenwick trees ? Isn't that useful ?

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

I have a different implementation for E , I am traversing on 1 match per function call by finding the people who haven't lost yet . It was giving TLE until I figured out ( yes figured out , because I didn't Google it ) how to traverse on Only set bits of a number in a given range ( range of bits ) . My submission

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

I think there exists a method for question D that is a little faster than the tutorial. The method used in the tutorial is to enumerate points, but I think it would be faster to enumerate edges. We divide the points into two groups, on x and on y, and discard the ones that satisfy both, since they cannot be composed. This way a pointer can be used to model the points that are between the two edges. Here the practice of my idea link

»
3 года назад, # |
  Проголосовать: нравится +17 Проголосовать: не нравится

I think there exists a method for question D that is a little faster than the tutorial. The method used in the tutorial is to enumerate points, but I think it would be faster to enumerate edges. We divide the points into two groups, on x and on y, and discard the ones that satisfy both, since they cannot be composed. This way a pointer can be used to model the points that are between the two edges. Here the practice of my idea link

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

Done E with a really funny complexity -> submission

Worst case of $$$O(2^{23}*23)$$$

»
3 года назад, # |
  Проголосовать: нравится -10 Проголосовать: не нравится

Your codes for D/E/F are soo looooong

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

Easy D approach -

Count no of points between each adjacent vertical lines. Let this count be n. Total no of pairs will be n*(n-1)/2. Subtract those pairs which lie on same horizontal line. This can be easily done using map.

Do the same for each adjacent horizontal lines

128428875

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

Hello, Can anybody please explain what does (1<<(1<<k))-1 represent in problem E??

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

    It means $$$2^{2^k}-1$$$. The << (bitwise shift) operator shifts the bits in the left number by the right number of times.

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

[deleted]

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

    Both $$$m$$$ and $$$n$$$ can be upto $$$2e5$$$. So yes, $$$O(mn)$$$ will exceed both memory and time limits.

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

Hi I was upsolving the C problem, can someone tell me why this wont pass the second test case? Thanks in advanced! my solution

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

problem C is interesting !

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

Can someone help me with my solution for problem C. So I came up with the same idea as the solution that a nice permutation must have at least 1 pair of i, j that i < j, a[i] is the largest number of the array and a[j] = a[i] — 1. I will call the largest number M. So using that, I will choose 2 position for M and M-1 , so there will be n*(n-1)/2 ways to place M and M-1. Suppose there are k number equal to M-1, there will be k*n*(n-1)/2 such ways. The remaining element can be placed anywhere so there will be (n-2)! ways. So in total there will be k*n*(n-1)/2*(n-2)! pair of nice permutation. But this formula gives the wrong answer for the 4th example test. I haven't known what is wrong with my solution yet so I hope u guys will help me with it. Thanks in advance!

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

    I'm struggling with the same sitaution have you figured out what's wrong with the approach @Dyln

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

      So when we use $$$C_n^2$$$ and multiply it with $$$(n-2)!$$$ it will count some cases multiple times because the positions of the second max elements are not fixed (ie. when the array is 1 1 2). Therefore, we have to fixed $$$k+1$$$ elements first and the max element will be placed anywhere but the last position, so our formula will be $$$A_n^{n-k-1}k!k$$$, which will simplify to $$$\frac{n!}{k+1}k$$$.

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

        Hey its still doubtful as by doing nC2 we ensure that the second (atleast) one is behind the max one. So how can it count multiple cases

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

          So let take a look at the array i mentioned: 1 1 2. First we take the first 1 (1st index) and the max value, then pick two random positions for them, let assume they are 1 and 2, so our permutation will be 3 1 2. But when we consider the second 1 (2nd index) and the max value, if we take position 1 and 3 then our permutation will also be 3 1 2. This permutation is counted twice because we didnt fix the position of the 1s. Therefore, the original formula is wrong although intuitively, it seems right XD.

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

There is a typo in the last line of paragraph 5, 1569D. strret->street :D @awoo

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

In C, this line of code if (cmx == 1) ans = (ans - sub + MOD) % MOD; Why do we use mod like this: (.. + MOD % MOD)? We already calculated 'ans' and 'sub' under MOD, why do we use it again in the if statement?

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

    you need to +MOD because ans-sub may be a negative number , you need to %MOD because if ans-sub is non-negative , the former +MOD will give a value greater than ( or equal to ) MOD so you have to modulo again