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

Автор chrome, история, 8 лет назад, По-английски

Hi there!

Tomorrow, at 15:00 MSK will be held Topcoder SRM 683.

Let's discuss problems after contest!

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

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

how to solve div1 250 ?

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

    I solved it using this technique.

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

    There will be some point such that you will not make moves crossing this point in your optimal solution. Therefore you can try all cyclic shifts, solve each of them as problem on array (where first and last elements aren't adjacent) and pick best result.

    How to solve problem for array: result is equal to sum abs(pref_sum_A[i]-pref_sum_B[i]) over all i. Idea is following: it makes no sense to move some element in opposite directions (you can cancel such pair of moves), therefore if you have X elements in prefix of first array and Y elements in prefix of second array, there will be abs(X-Y) moves through the cut after this prefix — because you have to make X=Y, and you'll be either moving items from suffix into prefix or from prefix into suffix — but not both.

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

      How to prove the first point? I can feel it intuitively, but dont know how to prove it.

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

        This is probably one of those problems in which the organizers don't actually expect you to prove it (I hate submitting unproven solutions, so these kinds of problems crush me q.q)

        Anyway, suppose the optimal solution crosses every point. Let's call a series of moves in a single direction a "segment", i.e. 1->2->3->4 is the segment 1->4.

        Obviously moving stones in a full circle is not optimal because it doesn't change anything, so let's ignore that case. The final sequence of moves can then be represented by an even number of segments that reverse direction, for example 1->4, 4<-8, 8->12, 12<-1.

        Consider the sums of the lengths of all odd and even segments. Without loss of generality, if the sum of all odd segments is larger than or equal to the length of all even segments, you can switch a stone from each odd segment to each even segment, giving you a solution that is just as good as the original one. Continue moving stones from odd segments to even segments until an odd segment has no more stones left, and you've created a solution that is also optimal and in which at least one point is never crossed.

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

      any proof or intuition behind your logic ?

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

      You can actually generalize this to get O(n) solution for the circular case too.

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

        Without an extra log? I can solve it in and an author explained me solution with ternary search. What about O(n)?

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

          Without giving a lot of spoilers, if we're thinking about the same thing, you actually don't need to sort and add an extra log, as you only need one element (and nth_element is linear).

          My practice room solution implements that idea if you're still confused.

          Edit: Actually, look at the solution below, it's much nicer.

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

          the origin of the problem is here, and O(n) average solution is described here

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

    I tried to find pairs of piles such that one has a surplus and the other has a deficit of stones. I used a greedy approach (taking the adjacent piles first, then piles with distance 2 and so on ... ). Is this O(n^2) approach wrong?

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

    Let X be the number of stones that passes through the border between 0 and 1 in 0->1 direction (if X is negative, it means that -X stones passes through the border in the opposite direction).

    Then, X+a[1]-b[1] stones must pass through the border between 1 and 2 in 1->2 direction, X+a[1]-b[1]+a[2]-b[2] stones between 2->3, ... and so on.

    Therefore the problem reduces to the following: find X that minimizes the sum |X| + |X+a[1]-b[1]| + |X+a[1]-b[1]+a[2]-b[2]| + ...

    This is equivalent to a well-known problem where you are given points on a line and you need to find a point that minimizes the sum of distances to the given points. The solution is the median.

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

Any ideas on how to solve Div 2 1000 ?

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

    http://ideone.com/LmPqxj — one but not so obvious DFS. In my code a variable ways denotes the number of subtrees with this vertex as the topmost vertex. And variable pref is the sum of sizes, needed for the answer. I process children one by one, always merging two first children into a new one. Merging two children a, b is as follows:

    ways = ways[a] * ways[b]
    pref = ways[a] * pref[b] + ways[b] * pref[a]
    
    • »
      »
      »
      8 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      I understand ways = ways[a] * ways[b] (to find the total subtrees), but I'm having trouble understanding why pref = ways[a] * pref[b] + ways[b] * pref[a] computes the total sum of sizes for the current node. Can you please elaborate?

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

One simple solution for Div1-Hard: the answer is 4^k * p(t) where p is a polynomial with degree is O(n+m). So we can get answers for k = 0, 1, ..., n+m by bruteforces, then get the answer for large k by Lagrange Interpolation. (Code: http://ideone.com/z1GXl8)

This solution is O(n^3) (assume n = m). In fact, the writer has an O(n^2) solution, but it looks very hard, so we reduced n to 100 to allow more solution to pass.

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

    Is it easy to see that p is a polynomial?

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

      I was a writer this time. cgy4ever did it in this way (just sketch):

      Consider for 0 ≤ i ≤ n, 0 ≤ j ≤ m as function of t. Then e(t + 1) = Ae(t), where A is some matrix. It gives that e(t) obey some reccurence, one can prove it is polynomial from here.

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

    One not so simple solution for Div1-Hard: If you rotate by 45deg ((x,y) -> (s,t)=(x+y,x-y)) then the s-coord and t-coord move independently.

    Where Ai, j is some constant with binomials and stuff. Because s,t move independently E(sitj) = E(si)E(tj). Let r = ds1 + ... + dst, each dsi being +-1 uniformly randomly, then

    If you expand ri you'll notice that any term with an odd power for any ds will have expected value 0, otherwise it'll be 1, so we just need to count those. You can do that with a dp in O(n^2), state being i and how many of the ds currently have odd power. Overall the algo can be implemented in O(n^2).

    Edit: Rip, i've reused the name t, I hope it's clear from the context which is which.

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

      Actually with some more thought I've sped it up to O(nlgnlgt). Basically everything can be sped up with fft. We have

      where the sum is over length t sequences a of non-negative even integers with sum j. r0, ... has generating function

      r(x) = (x0 / 0! + x2 / 2! + ...)t

      As we only need the first n+m terms of this we can just fast exponentiate using FFT in O(nlgnlgT) and then use r(x) to calculate E(ri)s. We can do similar FFTs to calculate E(si), E(ti)s from E(ri)s and then to calculate Ai, n + m - i s, which are the terms we need in our final sum (I left out that j = n+m-i in my first comment).

      C++ Code

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

How to solve Div1 500?

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

    For every prime p count vp(a0), vp(a1), ..., vp(an), where vp(x) is the largest k such that pk divides x. Sort these arrays. Then for the first number take the product of the largest vp(ai) for all p, for the second — the product of the second largest vp(ai) for all p and so on. It's obvious that this answer is optimal and reachable from the initial array.

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

    For each prime numbers its occurrences (after factorizing numbers) will be sorted by the exponent degree. Let's say that the input sequence is 25·38·51, 27·510, 23·34·54. Then, prime number 2 has its occurrences sorted as 27, 25, 23 and similarly for primes 3, 5. The final sequence should be 27·38·510, 25·34·54, 23·51.

    That was the intended solution. But I was retarted as a tester and I came up with much harder solution only. I simulate the process, carefully choosing the order of operations. I can explain if anybody wants it. Code — http://ideone.com/BCOUcE

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

Does anyone know how to break mincost-flow solution in 250-d1? I made two unsuccessful hacks because of it. :(

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

    The only finite edges are incident to either source or sink so there will be only n iterations of dijkstra. So it's O(n2log(n)), you can't break it.

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

      My MCMF code got broken by a random large case. Same for some others in my room.

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

        That's because you add O(n2) edges. You only need edges from source, to sink and between adjacent positions. Then you will have O(n) edges.

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

          Ah, yes. Can you please explain your graph construction (capacities and costs for the edges)?

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

            There are edges from the source to every position with zero cost and capacity max(a[i] - b[i], 0), edges from every position to the sink with zero cost and capacity max(b[i] - a[i], 0) and edges between adjacent positions with cost 1 and infinite capacity. I didn't write this solution because I thought that it would be an overkill. Instead I thought of another simpler solution but it turned out to be wrong.

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

How to solve Div 2 500?

I feel it is similar to GERGOVIA?

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

    O(N^2) Greedy.

    A solution only exists if the sum of both arrays are equal, if not output -1.

    Start with an empty set {}.

    Go from 1 to N, and at each step, solve for element number i. Maintain an invariant that all elements to your left have their target values ( all of them) so it makes no sense to change them, only look to the right.

    Let curr[] denote initial configuration, and goal[] denote the desired configuration.

    if curr[i] > initial[i]..You've excess, and since all elements to your left are with correct values, the excess must go to the right, you don't know where, but anyways, it has to move, so moving it to i + 1 does not make your answer worse.

    if initial[i] > curr[i]..Keep moving to the right, and adding elements till initial[i] = curr[i]. ( This is not the two pointers method, after you fix i, you will start again from i + 1).

    At step N, initial[N] must be equal curr[N] as you already fixed all values, and sums are equal.

    Clearly if initial[i] = curr[i] do nothing.

    Make sure to use long long when summing arrays.

    Note: The above strategy does not work for Div1 250.

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

web statistics hasn't been updated yet, why?