1

I need to efficiently find the max{S} such that S=(A[i]-A[j]) in a given range [i,j]. I am not able to find the solution other than the brute force solution where for every query iterate the array from index i to index j and find the solution. I am thinking of using two segment tree one for finding minimum and another one for finding maximum in a given range but since there is an additional constraint such that i<=j so this will not give correct answer in every case.

Constraint:i<=j
n- number of elements in an array (n<=10^6) 
q- number of Queries (q<=10^5)


Example:

Input
5
2 8 4 9 7
2
0 4
2 4

Output
4
2

Explanation:
Input consists of an array with 5 elements and then 2 queries.
1) In the range [0,4] - (8-4) = 4 is the answer
2) In the range [2,4] - (9-7) = 2 is the answer
user157920
  • 43
  • 4
  • what's your approach and show some code which you have done – Bhargav Modi Jul 21 '17 at 11:49
  • Why should the constraint i<=j even matter ? isnt it all symmetric ? Segment trees are all about finding common ancestor for two given nodes. I dont see any problem in that for the given constraint. – zeekhuge Jul 21 '17 at 11:54
  • @ZeekHuge, there can be cases when larger element in a range is after the smaller element in a range. – user157920 Jul 21 '17 at 12:23
  • I was able to tweak my segment tree by little bit and I got the required answer, do you have any other input example, on which I can try out my logic. I will paste my approach here right now – zenwraight Jul 21 '17 at 15:37

1 Answers1

0

This question seemed really interesting to me, now I don't know whether my approach is perfectly correct or not, but I gave it a try and it gives me correct result for the current input.

So according to my approach, I keep one segment tree to keep max values for all the ranges and another segment tree that stores the value for difference between the max of left side - max of right side.

Point to be noted here, why I am doing so is because we need A[i] - A[j] and i <= j, so if we keep on storing max of left range - max of right range, then we will always end up having the difference value and also i <= j.

Have a look at my code, to understand this more.

    #include <bits/stdc++.h>

    using namespace std;

    const int N = 1e5;  // limit for array size
    int n;  // array size
    int t[2 * N];
    int t_ans[2*N];

    void build1() {  // build the tree
      for (int i = n - 1; i > 0; --i) t[i] = max(t[i<<1],t[i<<1|1]);
    }

    void build2() {  // build the tree
      for (int i = n - 1; i > 0; --i) t_ans[i] = t[i<<1] - t[i<<1|1];
    }

    void modify(int p, int value) {  // set value at position p
      for (t[p += n] = value; p > 1; p >>= 1) t[p>>1] = t[p] + t[p^1];
    }

    int query(int l, int r) {  // sum on interval [l, r)
      int res = 0;
      for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
        if (l&1) res = max(res,t[l++]);
        if (r&1) res = max(res,t[--r]);
      }
      return res;
    }

    int query2(int l, int r) {  // sum on interval [l, r)
      int res = 0;
      for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
        if (l&1) res = max(res, t_ans[l++]);
        if (r&1) res = max(res, t_ans[--r]);
      }
      return res;
    }

    int main() {
      cin>>n;
      for (int i = 0; i < n; ++i) {
        scanf("%d", t + n + i);
      }
      build1();
      build2();

      /*
      For testing purpose only
      for(int i=0; i<2*n; i++) {
        cout<<t[i]<<" ";
      }
      cout<<endl;
      for(int i=0; i<2*n; i++) {
        cout<<t_ans[i]<<" ";
      }
      cout<<endl;
      */
      int q;
      cin>>q;
      for(int i=0; i<q; i++) {
        int l,r;
        cin>>l>>r;
        cout<<query2(l,r+1)<<endl;
      }

      return 0;
    }

I am keeping two segment trees, one tree for storing max range values and it's called t and another that stores max of difference and that is being stored in t_ans.

Now I call two different build methods, build1() builds segment tree for max values and build2() builds segment tree for difference between max of left tree - max of right tree.

Let me know if I made any error or mistakes in my current approach.

Hope this helps!

zenwraight
  • 2,002
  • 1
  • 10
  • 14
  • thanks for your solution but this algorithm will not work try few cases you will understand that this is even failing for simple cases as well. – user157920 Jul 21 '17 at 18:40
  • Hi @user157920 , can you provide me with some input cases, I didn't had much time to test it out – zenwraight Jul 21 '17 at 18:44
  • Hi @zenwraight, please find the sample test case for which this is failing 5(no of elements in array) 10 2 11 7 8 3(no of queries) 0 2 1 3 2 3 – user157920 Jul 22 '17 at 04:48