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

Автор netman, история, 8 лет назад, По-русски
Tutorial is loading...
Code
Tutorial is loading...
Code
Tutorial is loading...
Code
Tutorial is loading...
Code
Tutorial is loading...
C++ code
Java code
Разбор задач Codeforces Round 390 (Div. 2)
  • Проголосовать: нравится
  • +108
  • Проголосовать: не нравится

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

Auto comment: topic has been translated by netman (original revision, translated revision, compare)

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

The fastest editorial in 2017

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

Another solution of problem D. We use sweep line with events {segment_start, segment_end}. When segment starts we increase arr[pos_l]++, and when segment ends we decrease arr[pos_l]--. To find the answer, we need to check the k-th left-started segment in our array, each time for every event. If we are in pos and have segments_cnt >= k, we know that each of them has end-point >= pos, so our goal is to find k longest segments and answer is pos — po_l[k-th segment]+1. To implement arr[] we can use sparse segment tree. Code
Complexity is O(NlogN + Nlog109)

PS. Is it right complexity in editorial? Should it be O(NlogN + NlogR)?

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

    Solution in editorial has such complexity, because I sort events in every iteration of binary search. I know how to improve complexity, but it's not so important :)

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

    better solution for D, which is too simpler and also much more straight to code. We know the period we want is min(ri)-max(li) between all of k periods we chose. So I sort all of the periods as {li,ri} and just for li I want k-1 periods before it which the min(ri) of them should be maximal possible. I have a set in which I keep k-1 maximum ri of previous periods. And the ans is for any i(1<i<=n) ans = max(ans, min(l[i].secon ,st.begin()->first ) — l[i].firs + 1); Complexity is O(NlogN) 23597706 thank you netman.

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

      Nice :)) the best solution !

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

      Can u elaborate on how are you going to save indexes of coupons after every iteration.

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

        As I coded, I apply the algorithm twice. At the first one, I save the maximum intersection and then at the second one, when the answer is equal to the maximum I output the i(we are at it, now) and the elements in the set.

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

          Wow,That was simple. I was trying to update the ans in one pass and that was giving TLE. Thanks for the answer. Good solution

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

      It is amazing. Thank you

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

    Can you elaborate your approach using seg. tree? I am unabble to get it.

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

Could you explain more about binary_search in D ?

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

Я решил E за O(nmr + nrc).

Для каждой клетки предподсчитаем, какие строки шаблона можно приложить начиная с этой клетки: Зафиксируем строку таблицы и строку шаблона. Возьмем конкатенацию строки шаблона и строку таблицы (последнюю возможно придется повторить насколько раз, но длина будет все равно O(m + c)). Посчитаем на ней z-функцию, только при сравнении элементов на равенство будем использовать s[i + z[i]] == s[z[i]] || s[z[i]] == '?'. С помощью этих значений мы можем выполнить нужный предподсчет. Для всех пар это отработает за O(nr(m + c)

Теперь можно перебрать все клетки и пробовать к каждой из них прикладывать начало шаблона за O(nmr)

c++

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

    Словил вчера wa4 с той же идеей, но префикс функцией... 23605543

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

      Строку из таблицы иногда нужно добавить больше 2-х раз. Чтобы была достаточная длина. Например, у таблицы длина 2, у шаблона 100.

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

    z-функция работает, потому что равенство транзитивно. У вас равенство нетранзитивно.

    Например, на строчке a?b вы насчитаете 0 2 1, что не является правдой.

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

      у меня там просто 0 0 0. '?' прикладывается только к '?'. Я на контесте не вдавался в док-во корректности, так что все может быть. Это просто не первое место, где такая вещь с шаблонами проходила, а подумать над этим все время забывал.

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

        Да, это корректный алгоритм, я точно также сдал. Но только вот есть одна проблема.

        Из-за того, что z-функция может считаться неправильно для позиций, в которых записаны знаки вопроса, можно придумать тест, на котором она будет считаться за O(n2). Например, для такой строки :

        a?????...?aaaaaa...a (399 вопросов, потом 800 букв a)

        z-функция будет такой : 0, 0, 0, ..., 0, 800, 799, 798, ..., 1.

        Т.е. во всех позициях, где записана буква a, цикл будет полностью проходить до конца строки, следовательно суммарное время работы будет как-раз O(n2).

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

        Ну тогда на строчке a???...???aaa...aaa это квадрат?

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

          В теории да, это квадрат. И в теории это TL. Но это работает, т.к. нужно было делать специальные тесты против решения. Т.е. в данном контесте это рабочее решение.

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

            То, что оно получает OK, я и так вижу. Это не делает решение правильным. Такой тест сделать можно.

            Уметь сдавать медленные решения — это замечательный скилл. Но это же послеконтестовая дискуссия, сейчас мы заинтересованы не в получении OK, а в красивых решениях. Вы предложили интересный метод, но он оказался плохим. Странно оправдываться словами "ну тесты же плохие, значит решение норм".

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

    Сама z-функция может считаться неверно для подстрок с вопросами (меньше, чем нужно), но когда знаков вопроса уже нет, она считается верно (а нам это и нужно). Т.е. после последнего вопроса будут корректные значения ф-ции.

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

thanks for realy good problems

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

в Д можно еще по-другому. Отсортируем отрезки по левому концу. Переберем отрезок, левая граница которого и будет являться левой границей пересечения. Теперь из всех отрезков, левые концы к-ых не правее нас нам хочется выбрать К — 1 с наибольшими правыми концами. Корректность левых границ автоматически поддержано сортировкой(т.е. все хорошие отрезки уже рассмотрены), а чтобы выбрать максимальные К — 1 можно поддерживать сет из (К — 1) максимальных правых концов.

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

wrong solution!

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

Loved the first problem, had to think a bit out of the box.

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

I don't wanna be a hater, but at problem A, by "dividing" I understood that the array should be divided in 2 or more arrays. "1.Array sum is not zero. In this case we can divide array into one subarray A[1... n]." That's not called dividing, because you are left with one single array. If I'm wrong, please correct me. Thanks for reading this and I hope I didn't waste your time.

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

    Yes, you are wrong. As the problem statement point the dividing all of array into one array is correct.

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

I had some trouble debugging my implementation of Div2E editorial's solution, so I'll give some hints.

  1. If you build a straightforward Gz, i, j representation of Ti, j using std::bitset, shifting is reversed! This means that shift(Gz, x, y) should be implemented with b>>y instead of b<<y. This makes sense, because the "left" shift defined in the solution brings elements from positions with larger y indexes to positions with smaller y indexes. Using std::bitset, or any native integral types, this is actually a right shift!
  2. The shift is actually a rotate. In other words, b>>y is not enough. Use (b<<(m-y))|(b>>y) instead.
  3. Pattern might be larger than text, so don't forget to take y modulo m.

My implementation: 23653130

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

How would one go about solving D if the question was the union of all of the segments instead of the intersection?

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

    I think a bit about it!!! And I don't think it can be solved better than O(nk). Anyone else have an idea?!

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

      Can you share your method? The best I could think of its an O(kn^2) solution.

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

        Sure! First, we sort segments and remove the segments that are inside another segments. We can simply prove they are useless. Now if li > lj then ri > rj. We arrange the segments with their li. Define dp[i][j] equal to the maximum union of j segments from 1 to ith! We consider two condition for ith segment to fill dp[i][j]: If the previous picked segment have any share range with this, then we choose the leftmost segment that have share range with this as k and simply dp[i][j] = dp[k][j-1]+(ri-li+1)-(rk-li+1). and If not we can update dp[i][j] from maximum of dp[k][j-1](k from 1 to k-1) and then dp[i][j] = mx[k-1][j-1]+(ri-li+1). Am I wrong?!

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

          Ah, I missed out the dp transit optimization part, that's a neat observation.

          Could persistent data structure help improve the algorithm? The dp transition is always going to be shift one step to the right and add the same variable if a segment is "profitable".

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

            To be honest, I don't know about persistent data structure well! As I was thinking about it, actually, the updating is good enough to be much more optimizer! I will think about it tonight and I'll share the result(if I have any results)!

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

              Now I think more about it I don't think persistent data structure is a feasible data structure, as there is no way to update the next state merely from the latest state. As we have to update from both the just overlapping position and the just not overlapping position it is very hard to maintain the data structure that supports update function at every version.

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

Another greedy solution for D code.

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

My O(nlog(n)) solution using Sort and Heap for problem D (div2). 23736804

Algorithm:
 0 Keep tree vars: max for intersection length, l, r for final left and right bounds, go 1
 1 Sort segments by their left borders, go to 2 
 2 Keep Min Heap of size k to store right bounds. go to 3
 3 Traversing the segments, if the heap's size is less than k just add the segment's right bound to it, then go to 3. Else go to 4 
 4 Compare current segment's right bound with heap's peek, then go to 5
 5 If it is greater than peek, then just remove peek of the heap and add the current segment's right bound to the heap, then go to 6. Else go to 7.
 6 Calculate count of goods by taking difference of heap.peek()-cur.left+1. Update max, l, r and go to 7.
 7 Repeat 3 - 6 until we pass all the segments, then go to 8.
 8 If heap size is equals to k, then go 9, else go 10
 9 Calculate count of goods by taking difference of heap.peek()-cur.left+1.Update max, l, r and go to 10
 10 List k segments that contains segments [l,r]

To sum up sorting takes O(nlog(n)) traversing with heap operations also O(nlog(n)). Total time complexity is also O(nlog(n)).

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

Problem E tags contains "fft". Could someone give me a hint about that approach?