1

You are given a sequence A of N (N <= 50000) integers between -10000 and 10000. On this sequence you have to apply M (M <= 50000) operations: modify the i-th element in the sequence or for given x y print max{Ai + Ai+1 + .. + Aj | x<=i<=j<=y }.

Problem Link



I am using Segment Tree for this but i am not getting the correct output , please Help me where i have committed the mistake
CODE:

Making a Tree:

public static void maketree(int current , int a , int b ,int[] arr){

      if(b<a) return;

      if(b==a) {dp[current] = arr[a]; return ;}

      maketree(2*current, a, (a+b)/2, arr);

      maketree(2*current+1,1+ (a+b)/2, b, arr);

      if(dp[2*current]>0 && dp[2*current+1]>0) dp[current] = dp[2*current] + dp[2*current+1];
      else if(dp[2*current]>dp[2*current+1]) dp[current] = dp[2*current]; 
      else  dp[current] = dp[2*current+1]; 


}

Updating Function

public static void update(int current , int a , int b , int c , int value){

      if(a>b || c<a || c>b) return ;

      if(a==b){ dp[current] = value; return ; }

      update(2*current, a, (a+b)/2, c, value);

      update(2*current+1, (b+a)/2 +1, b, c, value);

      if(dp[2*current]>0 && dp[2*current+1]>0) dp[current] = dp[2*current] + dp[2*current+1];
      else if(dp[2*current]>dp[2*current+1]) dp[current] = dp[2*current]; 
      else  dp[current] = dp[2*current+1]; 



}

Query Function:

public static int query(int current , int a , int b , int i , int j){
        int ans =0;


        if(a>j || b<i || a>b) return Integer.MIN_VALUE;

        if(a>=i && b<=j) return dp[current];

        int x = query(2*current, a, (a+b)/2, i, j);
        int y = query(2*current+1, (a+b)/2 +1, b, i, j);

       if(x>0 && y>0) ans= x+y;
       else if(x>y) ans = x;
       else ans =y;





        return ans; 



}

I don;t know where i have made mistake please help , What will storage capacity required for dp array i.e. size of dp

OmG
  • 18,337
  • 10
  • 57
  • 90
user4415506
  • 109
  • 1
  • 7
  • The idea of your solution is completely incorrect(I mean the data you store in each node and the way you merge two nodes). – kraskevich Jan 09 '15 at 18:13

2 Answers2

1

when you are merging two nodes,then it may be like given below.execute any simple example so that you can feel it :)

void merge(node a , node b)
{

    sum = a.sum + b.sum;
    pre = max(a.pre , (a.sum + b.pre));
    suf = max(b.suf , (b.sum + a.suf));
    result = max(a.suf + b.pre,max(a.result , b.result));

}

  • what is `a.pre` `a.suf` and `a.result` please explain – user4415506 Jan 10 '15 at 04:49
  • If X has 2 children x1 and x2.then X.pre means sum of all descendent of x1 and left child of x2 .similarly X.suf means sum of all descendent of x2 and right child of x1.and X.res means combining X.pre and X.suff (which will be clearly contiguous!!) Which is largest sum.I hope this should clear your all doubt.just execute a simple example to have more feel of it. –  Jan 11 '15 at 17:39
0

it is quite overcomplicated imo...

int tree[1 << 17]; // 2 ^ 17 >= N * 2
int M = 1; //base of tree or sth i dont remember english name

int query(int L, int R){
  int res = -10000; //minimum possible value in array
  L += M - 1;
  R += M - 1;
  while(L <= R){
    if(L % 2 == 1) res = max(res, tree[L++];
    if(R % 2 == 0) res = max(res, tree[R++];
    L /= 2;
    R /= 2;
  }
  return res;
}

void update(int v, int value){
  v += M - 1;
  tree[v] = value;
  while(v > 0){
    v /= 2;
    tree[v] = max(tree[v * 2], tree[v * 2 + 1]);
  }
}

void make_tree(){
  int n;
  cin >> n;
  while(M < n) M *= 2; // M is half of the size of tree
  for(int i = 0;i < n;i++)
    cin >> tree[i + M]; // just reading input to tree;
  for(int i = M - 1;i > 0;i--) // first update for all nodes other than leafs
    tree[i] = max(tree[i * 2], tree[i * 2 + 1]); 
}