Автор awoo, история, 7 лет назад, По-русски

Привет, Codeforces!

28 апреля в 18:05 MSK состоится Educational Codeforces Round 20.

Продолжается серия образовательных раундов в рамках инициативы университета Harbour.Space! Подробности о сотрудничестве Harbour.Space и Codeforces можно прочитать в посте.

Раунд будет нерейтинговый. Соревнование будет проводиться по немного расширенным правилам ACM ICPC. После окончания раунда будет период времени длительностью в один день, в течение которого вы можете попробовать взломать абсолютно любое решение (в том числе свое). Причем исходный код будет предоставлен не только для чтения, но и для копирования.

Вам будет предложено 7 задач на 2 часа 15 минут. Возможно, задачи покажутся многим чуть сложнее, чем в прошлые два раунда, но мы надеемся, что каждый участник найдет среди них задачу себе по душе.

Раунд вместе со мной готовили Иван BledDest Андросов и Михаил MikeMirzayanov Мирзаянов.

Желаю удачи на раунде!

UPD: Разбор доступен по ссылке

Поздравляем победителей:

Rank Competitor Problems Solved Penalty
1 Um_nik 7 129
2 bmerry 7 160
3 kmjp 7 191
4 KrK 7 212
5 rajat1603 7 235

Поздравляем лучших взломщиков:

Rank Competitor Hack Count
1 halyavin 135:-25
2 n.grechiha 20
3 oipotato 17
4 tqyaaaaaaaang 16
5 GreenGrape 16:-3

Было сделано 324 успешных и 209 неудачных взломов.

И, наконец, поздравляем людей, отправивших первое полное решение по задаче:

Problem Competitor Penalty
A kmjp 0:02
B RockyB 0:02
C Lewin 0:07
D Um_nik 0:15
E eddy1021 0:20
F tanphatls987 0:07
G ODT 0:33

  • Проголосовать: нравится
  • +178
  • Проголосовать: не нравится

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

Hope everyone enjoy the contest. :)

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

Auto comment: topic has been updated by awoo (previous revision, new revision, compare).

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

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

The duration in Contests list is 2 hours.

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

What is time complexity needed for acc on C? I can't belive didn't passed.I found all factors of n in and got sorted array.It's easy to see that gcd|n and so we need to find largest such that k|n and that's just binary search on array with factors.I was 100% sure that this will pass.. Really looking forward for solution!

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

    root(N) passes pretty easily.

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

    you wrote: for(int i=1;i*i<=n;i++)

    i*i=1e10

    overflow, and TLE :D

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

      Thanks,hopefully Educational round :D

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

      yes,I get TLE because k*(k+1)/2 is greater than long long.my solution is sqrt(n).But I did't find the error.So I failed the test.What a sad story it is.

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

    First two solutions works in O(n). In the third one you have integer overflow in factorization, so for big n it is an infinite loop.

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

Why is my solution for Problem C not passing.?

My idea is suppose that mid is the gcd of all the numbers then, the smallest form of the numbers is

A = 1*mid, 2*mid, 3*mid, ..., k*mid.

Now consider n-sum(A); This value must be a multiple of mid; simply add this remainder to the last item in A.

We can find mid by binary search.

My solutions always fails on test 14. I think my logic is wrong but why?

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

    Because it isn't a monotonic function so you can't use binary search for it.

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

      No it is,that array of divisors is sorted,solution works.I got silly overflow because used int in loop.

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

        He didn't mention that he did binary search over the divisors so I guess he did it over all numbers. Btw, you don't need binary search, you needed to calculate all the divisors so simply see if it fits over all divisors, the complexity is the same.

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

    I misread your comment. Your solution is the same as mine. Maybe your "mid" value was not selected correctly. Did you check all the divisors of n to choose the optimal mid?

    You have to make sure that n / mid >= k(k+1) / 2

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

Problem G basically.

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

    One segment tree (used twice) is enough.

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

      i guess i did overkill as i had a normal segtree from [1..K] and a persistent segtree in each leaf node of this segtree.

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

      Can you please explain how?

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

        I just got AC with a normal segtree and an implicit segtree.

        What I did was maintain an implicit segtree over the range [1, N * K], and a normal segtree over the given array, i.e. [1, N].

        The invariant of the implicit segtree is that for every node, if it exists, it will store the correct minimum value of the range it represents. It will also store a lazy value, which if non zero, means that there was an update at some time on the range it represents, with the value of lazy.

        Now when you are updating on the implicit segtree, say the current node completely overlaps with the update interval, then I will mark the lazy value on this node as the current query's value, and free all the nodes in the subtree of this node, since they are not needed anymore.

        When I am querying, if I reach a node that completely overlaps with the query interval, and the node is allocated, I will just return the minimum value at this node (which is correct because of the invariant of the implicit segtree).

        If I reach a node that completely overlaps with the query interval, but hasn't been allocated, I will first see the lazy value of the closest allocated ancestor of the current node which has a non zero lazy value. If their exist an ancestor with a non zero lazy value, I will return that lazy value. If there doesn't exist any such ancestor, I will query over the segtree made over the original array, as this range hasn't been updated in any way.

        It's kind of hard to explain in words, you can try to read the code and see if it helps: Code

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

        Let's write down all values of l and r for all queries, sort them and remove duplicates. One can see that a range between two consecutive elements can be treated as a point (because no query splits it) and there're clearly O(q) such points.

        We can build a standard segment tree over this compressed array of query boundaries. Each position should contain a value equal to the smallest element in the given range in the initial array (we can find it using the same segment tree build over the input array. We need to handle "long" ranges carefully: if r - l > n, we can just return the minimum of the entire array). After that, each query is a range assignment/range max in this segment tree.

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

    so that's what div 1 people do after solving all the questions...make memes :P

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

Couldn't solve D because of writing while( ++idx && idx < n ) instead of while( ++idx < n )

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

Any idea how to solve F?

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

    dp[i] = number of subsequences with gcd i
    dp[i] = 2^c — dp[2i] — dp[3i] — dp[4i] — ..... where c = number of multiples of i.

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

    GCD is 1 if and only if GCD isn't multiple of a prime

    So you are looking for |G'(2) n G'(3) n G'(5)....| n is intersection and G(i) means answers where gcd is multiple of i and G'(i) is G negated. Negate this twice and you'll get |G(1)| — |G(2) U G(3) U G(5) ...| use inclusion-exclusion and there you go. G(i) = 2^(frequency of multiples of i) — 1

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

Is there anyone who may know how to solve problem F?

My solution is O(n log^2 max(a)) but I got TLE.

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

nice problems <3

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

Auto comment: topic has been updated by awoo (previous revision, new revision, compare).

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

Can anyone please explain the solution of problem C?

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    1. The intended gcd value should divide n.
    2. The minimum possible sum of a sequence of length k with a fixed gcd is equal to gcd + 2 * gcd + ... + k * gcd. Iterate over divisors in decreasing order and try all of them as gcd's. The first sequence sum that is less or equal to n gives you the answer (given you fix the last element if needed).
»
7 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Why does iterating over an array of all divisors get TLE in C? Isn't the max number of divisors quite a small number?

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

Почему если среди двух решений с соревнования взломали второе, то в положении стоит -1?

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

In Problem E, I don't understand the line There is no hand such that the absolute difference before this hand was equal to k., can anyone please clarify?