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

Автор NALP, 16 лет назад, По-русски
Доброго времени суток всем.

В этот чудесный летний день приглашаю вас принять участие в Codeforces Beta Round #19. Сегодня авторами задач для Вас буду я и Артем Рахов.

Также выражаю благодарность всем, кто помогает нам в организации этого соревнования: Михаилу Мирзаянову, Эдварду Давтяну  и Юлии Сатушиной.

Надеюсь, что вам понравится.
Всем успехов!

P.S. После начала соревнования вы сможете скачать условия на русском и на английском языках.

UPD. Контест окончен, всем спасибо за участие. Поздравляем победителя, единственного участника, который решил все предложенные задачи - kalinov
Вы можете посмотреть результаты и задачи.
  • Проголосовать: нравится
  • +46
  • Проголосовать: не нравится

16 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится
Если я правильно понял, дополнительные копии условий выложены на случай если сайт упадёт. Но если он таки упадёт - никто не узнает адреса ( по крайней мере на первых порах). Мне кажется, на будующее будет неплохой идеей дать возможность учасникам заранее скачать архив с условием, а потом выложить где-то ( к примеру, там же) пароль к архиву.
16 лет назад, скрыть # |
 
Проголосовать: нравится +12 Проголосовать: не нравится
Новый рекорд по количеству участников
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
I just missed registration, could you allow us to register just for a couple more minutes, please?
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
To late... The contest started.. Ohhh...
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
I can't log in. They are saying about a broken link just as I try to enter the contest :(

Can anybody help, please!
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
А что из себя тест 46 по задаче E представляет?
16 лет назад, скрыть # |
 
Проголосовать: нравится -12 Проголосовать: не нравится
I don't like this contest at all. Second task shouldn't be dynamic programming.
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Good problems. I'm using hashing on C, but still get TLE on test 21.
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
with KMP i guess ?
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Блин... Обидно, поздновато допер до 2 задачи... Минут бы на 10 пораньше...
Ну ладно, зато из 2 дивизиона легче выбираться)))
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
А когда будет разбор задач?
16 лет назад, скрыть # |
 
Проголосовать: нравится +12 Проголосовать: не нравится
Thanks for the great contest! Problem A is a typical implementation problem. Problem B is simple but not really obvious DP. Problem C is a very interesting problem with a lot of ways to solve it.
Well, I've solved problem C without hashing. Also, I didn't use KMP or Z-function. DP is the answer :) Lots of memory to store everything I need, lots of precalc operations and AC as a result. Was really pleasured to solve this problem.
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +5 Проголосовать: не нравится
    Well, maybe my solution is not the most popular one. So I should better describe it.
    Possibly I wasn't correct when I said that I didn't use Z-function. I didn't use the typical linear algorithm to find classic Z-function. The idea was to find for two given positions X and Y the length of the longest string starting from this positions.
    I've used classic DP(X, Y) to find a value of DP-function. But it is no use to store the value of DP-function for any values of X and Y. We should store it only for positions with the same letter. It's mentioned in the statement that the number of such positions is strongly limited.
    Then it's quite obvious how to use the value of DP-function to solve this problem in O(N) time.
16 лет назад, скрыть # |
 
Проголосовать: нравится -11 Проголосовать: не нравится
@admin , can u provide me the testcase file for problemA?
16 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

no delete option....i clicked so many times..as my internet is slow...

but there should be delete option..   :?

16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Good contest! I had a lot of fun solving problem B :-)
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Может кто-нибудь рассказать, как решать задачу D?
16 лет назад, скрыть # |
 
Проголосовать: нравится +20 Проголосовать: не нравится
I didn't use neither Suffix Arrays nor hashing, nor DP. I've just stored all distances between equal numbers and then performed exactly the same thing that is written in the statement, i.e. tried to remove repeats in the increasing order of their lengths. The main observation is that the distance between the numbers from the first half of the repeat and the respective numbers from the second half remains unchanged.
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
can anyone show me a good method to solve Problem E ? my alg is O(m*m), but sill TLE.
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +4 Проголосовать: не нравится
    Well, if you look at standings you can easily understand that O(m*m) will definitely fail, since a lot of people have TLE. It can be solved faster. The main observation is that if the required edges exist then there is an odd cycle and all edges in answer belong to this cycle. So the first thing to do is to find some odd cycle with DFS. Then you can delete this cycle from graph. If the resulting graph is not biparate, then answer is zero. Otherwise you can run dfs from each of the nodes on cycle marking the colors of nodes. The goal is to understand which cycle nodes have the same color and which opposite. So, you will get some statements like "Nodes x and y of cycle have the same color" or "Nodes x and y of cycle have the opposite color". Obviously each statement is equivalent to statement "Edge to be removed is on segment [x,y] of cycle" or "Edge to be removed is on segment [y,x] of cycle" (depending on (y - x) % 2). Number of statements is linear because they are generated by DFS, so we have problem to find which cycle edges are on all generated segments of cycle, this problem can be solved by usual methods (sorting etc.). I don't know if this problem can be solved in a less complicated way, but even this solution can be coded on contest.
    PS: sorry for my terrible english.
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +7 Проголосовать: не нравится
    There is an O(n+m) solution based on DFS graph analysis.

    Run a DFS to create a DFS forest. For each node x let color(x) be depth(x) mod 2.

    Now, the only edges that could violate this coloring are back-edges in this DFS forest. 

    If colors on two endpoints of a back-edge are the same, we call this back-edge BAD. Otherwise we call it GOOD.

    If there are no BAD back-edges at all then the graph is bipartite and you have to output each edge and we're done.

    If there is exactly 1 BAD back-edge then that back-edge is a part of solution because removing it causes the resulting graph to be bipartite. However, if there are more than 1 BAD back-edge then none of them is in the solution.

    Now we covered back-edges, but what about tree-edges.

    Observe a tree-edge u--v such that u is a parent of v in a DFS tree, and imagine that we swap colors for each node in a subtree rooted in v. 

    Obviously a tree-edge u--v is now invalid and has to be removed, but some of the back-edges have also changed states. If a BAD back-edge led from a node in a subtree rooted in v to a node higher than v, then that edge became GOOD back-edge and vice versa.

    So a tree-edge is a part of solution if all BAD back-edges in the graph and none OK back-edges connect a node from a subtree rooted in v with a node in the rest of the graph.

    It's possible to keep track the number of such BAD and GOOD back-edges as you do the DFS. For each node add-up back-edges from it's children, add back-edges that go from the node up the tree and subtract back-edges that go down the tree.

    That's it. I hope it helps.

    I liked the problemset too, especially this problem. Thanks to problemsetters!
16 лет назад, скрыть # |
 
Проголосовать: нравится +12 Проголосовать: не нравится
Люди добрые напишите разбор пожалуйста
16 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится
Problem -A
I am getting WA. I am not able to sort the "teams" properly . Though in the below code i have used sorting using #3 defined basis.

My  
<A HREF="http://ideone.com/djbUe">Code</A> 
is here. Can anyone tell where i am wrong.
Thanks for ur response.
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
sorry  the link i provided for my code is
http://ideone.com/djbUe
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Problem C is wonderful!
For 2 same letter Ai and Aj(i < j) , we call it a "match":
M[i].x = j - i , M[i].start = i.
It can be found that there are no more than 10N "match"s.
We sort them by x first , if equal , by start.
And just to consider each match and keep the left-bound.
If there are some i that:
for all i <= j <= i + u - 1 , M[j].x = u , M[j].start = M[j-1].start + 1
and M[j] >= left-bound
We make the left-bound to i + u - 1 + u.
The algorithm is O(10NlogN).
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
somebody can explain me what exactly does
" in decreasing order of the diference between scored and missed goals "
means?

I don't understand what missed goals are you refering to. .
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Can anyone explain how to solve B?
I´ve seen, that it is a DP problem with N*N state space, but what exactly is the state and what is the dynamic optimality of the problem?
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +1 Проголосовать: не нравится
    dp[m][s] = the minimal cost of a subset of items that you choose among the first m items so that the sum of (t_i+1) >= s (here i runs over the indices of the chosen items).
    The answer is dp[n][n]
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится +1 Проголосовать: не нравится
      Thanks, this looks logical once you´ve stated it.
      It still seems, however, somewhat unobvious (or rather indirect). Quite a lot of people solved it during the contest, I´ve spent about 1.5 hours without success.
      How did you come up with it during the contest? Could you, please, describe your thought process? (I´m trying to fix mine) :)
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится
        Yeah, me too, I often fail on this kind of DP. can someone change our thought process. Thx
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится +3 Проголосовать: не нравится
        My thought process was something like this:

        OK, this looks like DP or greedy. It's problem B so it might be greedy.

        How should I sort items? Should I always pay for the cheapest item? No, doesn't work. Should I pay for the item with largest time? No. What about items with t=0. 

        Well, I guess it isn't greedy.

        How would I write a recursive solution?

        For each item I should either pay for it or steal it. If I pay for it then I can steal some other items. Yeah, state should definitely contain the position in sequence and the sum of ti. 

        Well I guess that's it, I just keep track of amount of items I have bought and the amount of items I can steal. In fact if I add 1 to each ti then it's even simpler.

        That's it, more or less. It's hard to recall and describe exactly. 

        A lot of experience with DP and memoization helps ofcourse, but I think the best advice is to write or think about writing a simple recursive brute force solution and then figure what the state is.

        When thinking about recursive solution you should try to make it as iterative as possible, that is scan elements in order and decide what to do with it.
        • 16 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится
          Very nice, thanks.
          Knowing how successful contestants approach the problems is both interesting in itself and educating as well. I thinks it´s underrated as a means of teaching:)
        • 16 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится
          Can you explain your solution for problem D too?
          Thanks in advance.
          • 16 лет назад, скрыть # ^ |
             
            Проголосовать: нравится +1 Проголосовать: не нравится
            Collect points from add and remove commands and sort them first by x and break ties by y.

            Each point in a sequence can be active or inactive, and initially every point is  inactive.

            For each query "find x y" we have to find the first (because of the way we sorted the sequence) active point P in this sequence such that P.x > x and P.y > y

            To maintain this sequence we have to build interval tree on it. For each interval we keep track of the largest y of all active points in the interval. If there is no active point in the interval than this value is -inf.

            Updates (add and remove) are quite simple, just find the point in the sequence and update the value of the leaf (value becomes P.y on add commands or -inf on remove commands) and then go up the tree and update the value as a maximum of two children nodes.

            Find x0, y0 command is also quite simple, but it might not be so easy to understand why is it O(log n).

            Start from the root and do the following recursively:
            If the x coordinate of the rightmost point in the interval represented by this node is not greater than x0 then none of the points in the interval are good and so we cut this branch.
            If the topmost point in the interval represented by this node is not greater than y0 then none of the points in the interval are good and so we cut this branch.

            Search for a solution in the left branch.
            If no solution is found then search for a solution in the right branch.

            My source code for further details.
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится
       why t_i + 1, why not ti?
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
As of problem B, printf("%lld\n", ans); fails in test case 11.
But cout << ans << endl; is accepted.

I'm new at codeforces and don't know why printf("%lld") failed.
Do you know why?