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

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

Hello

Consider Array A. For any suffix of A compute the prefix with maximum average.

Example : A => 1 3 2 5 3
Suffix [2, 5) => 2 5 3
Answer => 3.5

Is there a better solution than O(N ^ 2) ??

UPD

IMAN_GH's comment :

Haghani solved the problem and here we have his solution :

sum[i] = a[0] + a[1] + .. + a[i — 1]
for any i consider point (i, sum[i])
if answer for suffix i equals j then (sum[j] — sum[i]) / (j — i) is maximum in all j > i.
it's solution is somthing like upper hull of some points. it solves by using stack with insert points in the hull and updating it.
if we insert points from right to left then answer for suffix i equals to the second point in the upper hull after adding point i.

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

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

Are the numbers positive?

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

UPD: it is also solvable with convex hull trick in O(n).

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

Example : A=> 1 3 2 5 3

Suffix [3,4) => 5

Answer => 5

Why you don't get Maximum the number??

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

Come on M_H_M!

Please do not waste others' time with terrible problems.

It can be solved with O(n) !!!

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

I think we can use the idea of prefix function. We wish to find array s[1],s[2],...s[n] where s[i] denotes length of prefix starting at a[i] with maximum average. Now when we want to find s[i]. We look to a[i] and this our initial prefix for s[i]. If s[i+1] is bigger than our current average then we jump to i + s[i+1] index and continue in the same way. Obviously, it is better than O(n^2) in average, but is there test case where it would take O(n^2) worst case? I can't prove that it is linear time. UPD. Oh, it is obvious O(N):). The point is that you cannot jump over some s[i] more than one time. So it O(N+N) = O(N).

»
10 лет назад, скрыть # |
Rev. 5  
Проголосовать: нравится -25 Проголосовать: не нравится

Consider suffix starting at i. Suppose that we have found the maximal average value "Mean". Then:

Mean * (j — i + 1) >= a[i] + a[i+1] + ... + a[j] or sum(a[k] — mean) <= 0 for i <= k <= j.

So if there is a prefix whose sum is > 0, we increase Mean, all < 0 we decrease Mean, "=" happens when it exists. We can use binary search to find Mean and it is O(nlogn). There is a linear time algorithm for it, but I do not remember.

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

You can find an O(n) algorithm here: http://arxiv.org/abs/cs/0311020

It's actually really easy to implement, so don't be scared :)

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

    I cant understand what it is saying, can you implement that?

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

    Actually the article gives online solution (we can add elements one by one to the end of the array) to find the segment with maximum density, but there are nothing there about finding maximum density suffixes of each prefix (they are finding ij not i * j). Also they are considering the general case when each value has also a weight and we have the constraints to the minimal and maximal sum of weights in answer.

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

      It's true they talk about finding ij not i * j, but in our specific case wouldn't it be simple to modify the algorithm to print the correct i? Something like:

      r[-1] = -1
      r[j] = j+1 for all other j
      for j from 0 to n-1
          update(j);
          print the average of [phi[q-2], phi[q-1])
      

      We don't even need function lbest() at all in this case.

      Edit: I'm being hunted by WAs even in cf comments Edit 2: also, this is equivalent to the solution above, as phi is basically i, i+s[i], i+s[i]+s[i+s[i]], etc. But it was given without any proof, so putting it in this way should make it more obvious why it is correct.

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

What if it was (a[i]*a[i+k-1]+a[i+1]*a[i+k-2]+...+a[i+(k-1)/2]*a[i+k/2])/k ? I don't think that it would be better than O(N*N)

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

Haghani solved the problem and here we have his solution :

sum[i] = a[0] + a[1] + .. + a[i-1]
for any i consider point (i, sum[i])
if answer for suffix i equals j then (sum[j]-sum[i]) / (j-i) is maximum in all j > i.
it's solution is somthing like upper hull of some points. it solves by using stack with insert points in the hull and updating it.
if we insert points from right to left then answer for suffix i equals to the second point in the upper hull after adding point i.
so problem solved O(N)

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

Such a NICE Problem! It was really FANTASTIC!