Problem:
Range Add Query (RAQ)

Write a program which manipulates a sequence A = {a1, a2, . . . , an} with the following operations:

add(s, t, x): add x to as, as+1, ..., at.

get(i): output the value of ai.

Note that the initial values of ai (i = 1, 2, . . . , n) are 0.

Input

n q
query1
query2
:
queryq

In the first line, n (the number of elements in A) and q (the number of queries) are given. Then, ith query queryi is given in the following format:

0 s t x

or

1 t

The first digit represents the type of the query. '0' denotes add(s, t, x) and '1' denotes get(i).

Output

For each get operation, print the value.

Constraints

1 ≤ n ≤ 100000

1 ≤ q ≤ 100000

1 ≤ s ≤ t ≤ n

1 ≤ i ≤ n

0 ≤ x ≤ 1000

Sample Input 1

3 5
0 1 2 1
0 2 3 2
0 3 3 3
1 2
1 3

Sample Output 1

3
5

Sample Input 2

4 3
1 2
0 1 4 1
1 2

Sample Output 2

0
1

Solution in C (judge verdict: Accepted)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define ROOT 1

// getLeftChildIndex returns the index of the left child of index.
int getLeftChildIndex(int index)
{
  return 2*index;
}

// getRightChildIndex returns the index of the right child of index.
int getRightChildIndex(int index)
{
  return 2*index+1;
}

// getParentIndex returns the index of the parent of index.
int getParentIndex(int index)
{
  return index/2;
}

// getLeftBoundIndex returns the farthest left leaf index which index contains.
int getLeftBoundIndex(int treeLeavesLength, int index)
{
  while ( index < treeLeavesLength )
    index = getLeftChildIndex(index);
  return index-treeLeavesLength;
}

// getRightBoundIndex returns the farthest right leaf index which index contains.
int getRightBoundIndex(int treeLeavesLength, int index)
{
  while ( index < treeLeavesLength )
    index = getRightChildIndex(index);
  return index-treeLeavesLength;
}

// addToRange adds the value toadd from left to right in the tree.
void addToRange(int *tree, int treeLeavesLength, int currentIndex, int leftLeaf, int rightLeaf, int toadd)
{
  int leftBound = getLeftBoundIndex(treeLeavesLength, currentIndex),
    rightBound = getRightBoundIndex(treeLeavesLength, currentIndex);
  // if the proper node (currentIndex) has been found
  if ( leftBound == leftLeaf && rightBound == rightLeaf )
    {
      tree[currentIndex] += toadd;
      return;
    }
  // if the range lies in the left subtree
  if ( rightLeaf <= getRightBoundIndex(treeLeavesLength, getLeftChildIndex(currentIndex)) )
    {
      addToRange(tree, treeLeavesLength, getLeftChildIndex(currentIndex), leftLeaf, rightLeaf, toadd);
    }
  // if the range lies in the right subtree
  else if ( leftLeaf >= getLeftBoundIndex(treeLeavesLength, getRightChildIndex(currentIndex)) )
    {
      addToRange(tree, treeLeavesLength, getRightChildIndex(currentIndex), leftLeaf, rightLeaf, toadd);
    }
  // if the range lies in both subtrees
  else
    {
      int leftIndex = getLeftChildIndex(currentIndex),
	rightIndex = getRightChildIndex(currentIndex);
      // left piece
      addToRange(tree, treeLeavesLength, leftIndex, leftLeaf, getRightBoundIndex(treeLeavesLength, leftIndex), toadd);
      // right piece
      addToRange(tree, treeLeavesLength, rightIndex, getLeftBoundIndex(treeLeavesLength, rightIndex), rightLeaf, toadd);
    }
  return;
}

// printIndex prints the value at index in the leaves of the tree by summing along the branch from the root down.
void printIndex(int *tree, int treeLeavesLength, int leafIndex)
{
  int currentIndex = treeLeavesLength+leafIndex,
    output = tree[currentIndex];
  while ( currentIndex != ROOT )
    {
      currentIndex = getParentIndex(currentIndex);
      output += tree[currentIndex];
    }
  printf("%d\n", output);
  return;
}

int main(){
  size_t length, treeLeavesLength = 1;
  int numberOfQueries, i;
  scanf(" %lu %d", &length, &numberOfQueries);
  // find the length of the array to allocate for a tree with length leaves
  while ( treeLeavesLength < length )
    {
      treeLeavesLength <<= 1;
    }
  int *tree = (int *) malloc(sizeof(int[2*treeLeavesLength]));
  memset(tree, 0, 2*treeLeavesLength);
  // read in queries
  int query;
  for ( i = 0; i < numberOfQueries; i++ )
    {
      scanf(" %d", &query);
      // query is for addition
      if ( !query )
	{
	  int left, right, toadd;
	  scanf(" %d %d %d", &left, &right, &toadd);
	  addToRange(tree, treeLeavesLength, ROOT, left-1, right-1, toadd);
	}
      // query is for a get command
      else
	{
	  int index;
	  scanf(" %d", &index);
	  printIndex(tree, treeLeavesLength, index-1);
	}
    }
  free(tree);
  return 0;
}