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)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Math;
using static Reader;
using MethodImplAttribute = System.Runtime.CompilerServices.MethodImplAttribute;
using MethodImplOptions = System.Runtime.CompilerServices.MethodImplOptions;

public static class P
{
    public static void Main()
    {
        int n = NextInt;
        int q = NextInt;
        StringBuilder builder = new StringBuilder();
        var segTree = new RangeGetSegmentTree<int>(n, new AbelianMonoid<int>((x, y) => x + y, 0));
        for (int i = 0; i < q; i++)
        {
            if (NextInt == 0)
            {
                segTree.Operate(NextInt - 1, NextInt - 1, NextInt);
            }
            else
            {
                Console.WriteLine(segTree[NextInt - 1]);
            }
        }
    }
}

static class Reader
{
    const int BUF_SIZE = 1 << 12;
    static Stream Stream = Console.OpenStandardInput();
    static byte[] Buffer = new byte[BUF_SIZE];
    static int ptr = BUF_SIZE - 1;
    static void Move() { if (++ptr >= Buffer.Length) { Stream.Read(Buffer, 0, BUF_SIZE); ptr = 0; } }
    public static int NextInt
    {
        get
        {
            int res = 0; while (Buffer[ptr] < 48) Move();
            do { res = res * 10 + (Buffer[ptr] ^ 48); Move(); } while (48 <= Buffer[ptr]);
            return res;
        }
    }
}

class Monoid<T>
{
    public Func<T, T, T> Operation { get; }
    public T Identity { get; }

    public Monoid(Func<T, T, T> operation, T identity)
    {
        Operation = operation;
        Identity = identity;
    }
}

class AbelianMonoid<T> : Monoid<T>
{
    public AbelianMonoid(Func<T, T, T> operation, T identity) : base(operation, identity) { }
}

class RangeGetSegmentTree<T>
{
    public readonly int Size;
    readonly bool IsCommutative;
    Monoid<T> Monoid;
    T[] Operators;
    int Height;
    int LeafCount;

    public RangeGetSegmentTree(int size, Monoid<T> monoid)
    {
        Size = size;
        Monoid = monoid;
        Height = 1;
        LeafCount = 1;
        while (LeafCount < size) { Height++; LeafCount <<= 1; }
        Operators = new T[LeafCount << 1];
        for (int i = 0; i < Operators.Length; i++)
            Operators[i] = monoid.Identity;
    }
    public RangeGetSegmentTree(int size, AbelianMonoid<T> monoid) : this(size, monoid as Monoid<T>) { IsCommutative = true; }

    public T this[int index]
    {
        get { return Query(index); }
        set { Propagate(index += LeafCount); Operators[index] = value; }
    }

    public void Operate(int i, T x)
    {
        i += LeafCount;
        if (!IsCommutative) Propagate(i);
        Operators[i] = Monoid.Operation(Operators[i], x);
    }

    public void Operate(int l, int r, T x)
    {
        l += LeafCount;
        r += LeafCount;
        if (!IsCommutative) Propagate(l, r);
        while (l <= r)
        {
            if ((l & 1) == 1) Operators[l] = Monoid.Operation(Operators[l], x);
            if ((r & 1) == 0) Operators[r] = Monoid.Operation(Operators[r], x);
            l = (l + 1) / 2;
            r = (r - 1) / 2;
        }
    }

    public T Query(int index)
    {
        index += LeafCount;
        Propagate(index);
        return Operators[index];
    }

    private void Eval(int section)
    {
        var leftChild = section << 1;
        var rightChild = leftChild | 1;
        Operators[leftChild] = Monoid.Operation(Operators[leftChild], Operators[section]);
        Operators[rightChild] = Monoid.Operation(Operators[rightChild], Operators[section]);
        Operators[section] = Monoid.Identity;
    }

    private void Propagate(int sectionIndex)
    {
        for (int i = Height - 1; i >= 1; i--)
            Eval(sectionIndex >> i);
    }

    private void Propagate(int l, int r)
    {
        if (l == r) { Propagate(l); return; }
        int xor = l ^ r, i = Height - 1;
        for (; (xor >> i) == 0; i--) { Eval(l >> i); }
        for (; i >= 1; i--) { Eval(l >> i); Eval(r >> i); }
    }
}