Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to increment all values in an array interval by a given amount

Suppose i have an array A of length L. I will be given n intervals(i,j) and i have to increment all values between A[i] and A[j].Which data structure would be most suitable for the given operations?
The intervals are known beforehand.

like image 318
SHB Avatar asked Aug 23 '13 17:08

SHB


People also ask

How do you increment all values in an array?

To increment a value in an array, you can use the addition assignment (+=) operator, e.g. arr[0] += 1 . The operator adds the value of the right operand to the array element at the specific index and assigns the result to the element.

Can we increment an array?

No, it's not OK to increment an array. Although arrays are freely convertible to pointers, they are not pointers. Therefore, writing a++ will trigger an error.

What happens when you increment an array?

creates an array (which means its location is FIXED), it is not the same thing as a pointer as a pointers location can be moved. The array is default-initialized with the contents "one two three"; You can change the contents of the array as log as it doesn't grow in size, but you can't move arr.


2 Answers

You can get O(N + M). Keep an extra increment array B the same size of A initially empty (filled with 0). If you need to increment the range (i, j) with value k then do B[i] += k and B[j + 1] -= k

Now do a partial sum transformation in B, considering you're indexing from 0:

for (int i = 1; i < N; ++i) B[i] += B[i - 1];

And now the final values of A are A[i] + B[i]

like image 119
adrian.budau Avatar answered Sep 23 '22 12:09

adrian.budau


break all intervals into start and end indexes: s_i,e_i for the i-th interval which starts including s_i and ends excluding e_i

sort all s_i-s as an array S sort all e_i-s as an array E

set increment to zero start a linear scan of the input and add increment to everyone, in each loop if the next s_i is the current index increment increment if the next e_i is index decement increment

inc=0
s=<PriorityQueue of interval startindexes>
e=<PriorityQueue of interval endindexes>
for(i=0;i<n;i++){
  if( inc == 0 ){
    // skip adding zeros
    i=min(s.peek(),e.peek())
  }
  while( s.peek() == i ) {
    s.pop();
    inc++;
  }
  while( e.peek() == i ) {
    e.pop();
    inc--;
  }
  a[i]+=inc;
}

complexity(without skipping nonincremented elements): O(n+m*log(m)) // m is the number of intervals if n>>m then it's O(n)

complexity when skipping elements: O( min( n , \sum length(I_i) ) ), where length(I_i)=e_i-s_i

like image 38
Zoltán Haindrich Avatar answered Sep 21 '22 12:09

Zoltán Haindrich