@Test
  public void testFenwickTree() {
    nums = new int[] {3, 4, 9, 1, 4, 7, 6, 0};

    testClass = new FenwickTree(nums);
    testRangeSum();

    int val = +3;
    int updateIdx = 4;
    nums[updateIdx] += val;
    testClass.updateTree(updateIdx, val);
    testRangeSum();

    val = -6;
    updateIdx = 3;
    nums[updateIdx] += val;
    testClass.updateTree(updateIdx, val);
    testRangeSum();

    val = 7;
    updateIdx = 0;
    nums[updateIdx] -= val;
    testClass.updateTree(updateIdx, -val);

    val = -4;
    updateIdx = 1;
    nums[updateIdx] += val;
    testClass.updateTree(updateIdx, val);

    testRangeSum();
  }
 public static FenwickTree fenwickTree(long[] A) {
   FenwickTree fw = new FenwickTree(A.length);
   for (int i = 0; i < A.length; i++) {
     fw.addValue(i + 1, A[i]);
   }
   return fw;
 }
 @Test
 public void testGetValue() {
   int n = 2000;
   long[] A = randomArray(n);
   FenwickTree fw = fenwickTree(A);
   for (int i = 0; i < A.length; i++) {
     assertEquals(A[i], fw.getValue(i + 1));
   }
 }
 @Test
 public void testGetMax() {
   int n = 500;
   long[] A = randomArray(n);
   FenwickTree fw = fenwickTree(A);
   for (int i = 0; i < A.length; i++) {
     assertEquals(getMax(A, i), fw.getMax(i + 1));
   }
 }
 @Test
 public void testGetSum() {
   int n = 2000;
   long[] A = randomArray(n);
   FenwickTree fw = fenwickTree(A);
   for (int i = 0, cumul = 0; i < A.length; i++) {
     cumul += A[i];
     assertEquals(cumul, fw.getSum(i + 1));
   }
 }
 @Test
 public void testAddValue() {
   int n = 2000;
   FenwickTree fw = new FenwickTree(n);
   long[] A = randomArray(n);
   for (int i = 0; i < A.length; i++) {
     fw.addValue(i + 1, A[i]);
   }
   long[] B = fw.toArray();
   assertArrayEquals(A, B);
 }
 @Test
 public void testGetRangeSum() {
   int n = 500;
   long[] A = randomArray(n);
   FenwickTree fw = fenwickTree(A);
   for (int i = 0; i < A.length; i++) {
     for (int j = i; j < A.length; j++) {
       long sum = rangeSum(A, i, j);
       assertEquals(sum, fw.getRangeSum(i + 1, j + 1));
     }
   }
 }
 @Test
 public void testFindHigherValueIndex() {
   int n = 500;
   long[] A = randomArray(n);
   FenwickTree fw = fenwickTree(A);
   for (int i = 0; i < A.length; i++) {
     long sum = fw.getSum(i + 1);
     assertEquals(findHigherSumIndex(A, sum) + 1, fw.findHigherSumIndex(sum));
   }
   long sum = 10000000;
   assertEquals(findHigherSumIndex(A, sum) + 1, fw.findHigherSumIndex(sum));
   sum = -10000000;
   assertEquals(findHigherSumIndex(A, sum) + 1, fw.findHigherSumIndex(sum));
 }
 @Test
 public void testAddValueToRange() {
   int n = 500;
   long[] A = randomArray(n);
   FenwickTree fw = fenwickTree(A);
   for (int i = 0; i < A.length; i++) {
     for (int j = i; j < A.length; j++) {
       long value = random.nextInt(100);
       addValueToRange(A, i, j, value);
       fw.addValueToRange(i + 1, j + 1, value);
     }
   }
   long[] B = fw.toArray();
   assertArrayEquals(A, B);
 }
  private void testRangeSum() {
    long actualSum = 0;
    long expSum = 0;
    for (int i = 0; i < nums.length; i++) {
      expSum = 0;
      for (int j = i; j < nums.length; j++) {
        expSum += nums[j];
        actualSum = testClass.getSum(i, j);

        if (expSum != actualSum) {
          fail("problem for sum from -->" + i + " to -->" + j);
        }
      }
    }
  }