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

Автор Madiyar, 12 лет назад, По-английски

Single Round Match 630 will be held at 05:00 Fri Moscow time.

Let's discuss here problems after the contest.

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

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

Don't oversleep this round :)

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

а как решать 500?

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

    Посмотрим 2 соседних позиции в суфф массиве. Пусть это a и b. Тогда если a + 1 стоит в массиве раньше, чем b + 1, то мы можем поставить на эти позиции одинаковые символы, а если нет, то обязаны поставить разные. Ответ — сколько раз надо поставить разные + 1

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

500 Div1 is easier than 250, isn't it?

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

Very strange to see the same code Failed at contest and Passed on practice system test and also on the webpage I see that
Expected Results "Exists"
FAILED — Result: "Exists"
I think there are something wrong ,hope I get a reply.

http://community.topcoder.com/stat?c=problem_solution&rm=323315&rd=16061&pm=13287&cr=22882911

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

Given a suffix array. Is it possible to find the lexicographically smallest string that satisfies that array?

I was trying something like this for div2 1000, but couldn't came up with any correct idea to find the lexicographically smallest string for a given suffix array...

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

    In fact "find the lexicographically smallest string", "is that string lexicographically smallest", "how many different characters do we need" can be solved by same way.

    I don't know which one is easy and which one is hard, but there is one reason for using "is that string lexicographically smallest" as Div2-Hard: the algorithm "change one character (decrease by 1 if it is not 'a') and check if the SA remains same." can pass, and I thought some people can come up with it.

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

Can someone explain me the right approach to Div.2 500 (or at least give some hint)? My idea was to use Floyd-Warshall's algo, but then I wasn't able to figure out what to do next and got stuck.

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

How to solve div.1 500? Sorry that I'm not familiar with string suffix structures.

I just saw many solutions get 490+ points and I guess it will be very tricky.

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

hey all the genius plz help me Need Help here. Link is http://mirror.codeforces.com/blog/entry/13505

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

Any ideas how to solve div1 1000?

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

    I guess it is 2-sat ...

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

    The official solution involves 2-SAT, however there was another brute-force-like solution, which passed system test and was working several times faster than the intended one on all test cases we've tried. Unfortunately, we don't know neither how to prove it or how to break it. I think cgy4ever can describe his 2-SAT solution better than me, so I'll describe mine. Maybe someone can prove it or provide a counterexample.

    The idea is quite simple. Let's maintain the minimum and maximum possible value for each variable. At the very beginning they are [1, 100] for all N variables. On each step of the recursion we do the following:

    1) Output the answer if all intervals have length 1.

    2) Repeatedly try to shorten each interval if its ends are conflicting with some other intervals. Stop when we can't change any interval without making any assumptions (i.e. we cut intervals' ends only if we know they conflict with other intervals without making any guesses and going deeper into recursion).

    3) If after the previous procedure some interval has length 0, go out of the recursion.

    4) Take any interval that has length greater than 1 and try to fix the corresponding variable's value (i.e. iterate over all values from its interval). When we fix it's value to X, replace its interval by [X, X] and make recursive call (i.e. go to 1).

    5) Output {} if the recursion didn't find any answer.

    The reason why I think it works is following. I tried to run it against a lot of random test cases and couldn't find any single one where we should go out of the recursion at least once (except for the ones in item #3 in the list above). That's why I suspect it makes exactly N recursion steps and on each one it fixes one variable.

    UPD: I've submitted it to the practice room and its maximum running time is 68ms.

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

      System tests are weak then — I successfully challenged your solution

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

        Cool, fortunately there were no submissions like this during the contest.

        Actually, the original version of my solution had one more optimization: on each recursion step I was choosing the shortest interval among those with length greater than 1. But later I've noticed that even without this it passes system test, so I removed it from the code. Does your test case breaks this version as well? If yes, could you share the test case?

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

          Yes, my test case should break this version too: n=100, x99-x100=0, x99+x100=3

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

            Oh well, I only considered test cases where the answer exists. Of course, it's possible to add something like 'if clock() > 1.85 return {}', but this is kind of cheating and it will make the solution ugly.

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

              x1+x100>=51
              x99-x100=0
              x99+x100<100

              x1+xi>=52 for 1<i<99 (if you have an interval length optimization).

              For this test answer exists, but your solution will still fail on it.

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

                Why should it fail on this test case? After it fix the first variable to [1, 1] and go to the next step of the recursion, it'll first shorten the 100th interval to [50, 100], then the 99th interval to [50, 100] and then it'll notice an error and will return to the previous level. That's because the 2nd step is being applied repeatedly, until no changes are possible.

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

    Yes, the intended solution is 2-SAT.

    For each x[i], we add 99 variables to the 2-SAT system: (x[i]>=2), (x[i]>=3), (x[i]>=4), ..., (x[i]>=100). And we have: (x[i]>=100) -> (x[i]>=99), (x[i]>=99) -> (x[i]>=98), ...

    Then what is amazing is that all conditions can be described in this 2-SAT system. For example if we have x[1] * x[2] >= 50, then it can described as (x[1]<2) -> (x[2]>=50), (x[1]<3) -> (x[2]>=25), (x[1]<4) -> (x[2]>=17), ....

    And you need to think about how to handle these 20 different cases: 4 operations * 5 relations.

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

Can anyone please explain the solution for Div 1 500? I saw many codes and they all do something like if(p[sa[i]+1] > p[sa[i-1]+1]) ans++;, where p[i] marks the position of i in the suffix array. I don't have the faintest idea why that would work and I'm feeling really stupid now. Is it really that obvious?

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

    No, that need some insights, but you don't need to know some advanced knowledge about suffix struct.

    Suppose we know that the rank of each suffix of string S is {2, 3, 0, 1}, then we know s[2]s[3] < s[3] < s[0]s[1]s[2]s[3] < s[1]s[2]s[3]. Thus we know s[2] <= s[3] <= s[0] <= s[1].

    Now we need to know if we can set s[2] = s[3] (and something like s[3] = s[0] and s[0] = s[1]): we must ensure s[2]s[3] < s[3] still holds, that means we need s[3] < "" (or, suffix[3] < suffix[4]), that is not true. So we know s[2] < s[3]. Also we can know s[3] can be equals to s[0] since suffix[3+1] < suffix[0+1].

    After that we can allocate letters into s[]. s[2] = a, since s[2] < s[3], we set s[3] = b and so on.

    And now you can see why that one line of code can work.