Problem:


RSQ and 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.

  
getSum(s, t): report the sum of as, as+1, ..., at.

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 s t

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

Output

For each getSum operation, print the sum;

Constraints

1 ≤ n ≤ 100000

1 ≤ q ≤ 100000

  1 ≤ s ≤ t ≤ n

  0 ≤ x < 1000

Sample Input 1

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

Sample Output 1

4
8

Sample Input 2

4 3
1 1 4
0 1 4 1
1 1 4

Sample Output 2

0
4



Sample input:
3 5
0 1 2 1
0 2 3 2
0 3 3 3
1 1 2
1 2 3


Sample output:
4
8

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline

class LazyPropSegmentTree:
    def __init__(self, lst, op, apply, comp, e, identity):
        self.n = len(lst)
        self.depth = (self.n - 1).bit_length()
        self.N = 1 << self.depth
        self.op = op # binary operation of elements
        self.apply = apply # function to apply to an element
        self.comp = comp # composition of functions
        self.e = e # identity element w.r.t. op
        self.identity = identity # identity element w.r.t. comp
        self.v, self.length = self._build(lst) # self.v is set to be 1-indexed for simplicity
        self.lazy = [self.identity] * (2 * self.N)
    
    def __getitem__(self, i):
        return self.fold(i, i+1)
    
    def _build(self, lst):
        # construction of a tree
        # total 2 * self.N elements (tree[0] is not used)
        e, N, op = self.e, self.N, self.op
        tree = [e] * N + lst + [e] * (N - self.n)
        length = [1] * (2 * N)
        for i in range(N - 1, 0, -1):
            lc, rc = i << 1, (i << 1)|1
            tree[i] = op(tree[lc], tree[rc])
            length[i] = length[lc] + length[rc]
        return tree, length
    
    def _indices(self, l, r):
        left = l + self.N; right = r + self.N
        left //= (left & (-left)); right //= (right & (-right))
        left >>= 1; right >>= 1
        while left != right:
            if left > right: yield left; left >>= 1
            else: yield right; right >>= 1
        while left > 0: yield left; left >>= 1
    
    # propagate self.lazy and self.v in a top-down manner
    def _propagate_topdown(self, *indices):
        identity, v, lazy, length, apply, comp = self.identity, self.v, self.lazy, self.length, self.apply, self.comp
        for k in reversed(indices):
            x = lazy[k]
            if x == identity: continue
            lc, rc = k << 1, (k << 1) | 1
            lazy[lc] = comp(lazy[lc], x)
            lazy[rc] = comp(lazy[rc], x)
            v[lc] = apply(v[lc], x, length[lc])
            v[rc] = apply(v[rc], x, length[rc])
            lazy[k] = identity # propagated

    # propagate self.v in a bottom-up manner
    def _propagate_bottomup(self, indices):
        v, op = self.v, self.op
        for k in indices: v[k] = op(v[k << 1], v[(k << 1)|1])

    # update for the query interval [l, r) with function x
    def update(self, l, r, x):
        *indices, = self._indices(l, r)
        self._propagate_topdown(*indices)
        
        N, v, lazy, length, apply, comp = self.N, self.v, self.lazy, self.length, self.apply, self.comp
        
        # update self.v and self.lazy for the query interval [l, r)
        left = l + N; right = r + N
        if left & 1: v[left] = apply(v[left], x, length[left]); left += 1
        if right & 1: right -= 1; v[right] = apply(v[right], x, length[right])
        left >>= 1; right >>= 1
        while left < right:
            if left & 1:
                lazy[left] = comp(lazy[left], x)
                v[left] = apply(v[left], x, length[left])
                left += 1
            if right & 1:
                right -= 1
                lazy[right] = comp(lazy[right], x)
                v[right] = apply(v[right], x, length[right])
            left >>= 1; right >>= 1
        self._propagate_bottomup(indices)
    
    # returns answer for the query interval [l, r)
    def fold(self, l, r):
        self._propagate_topdown(*self._indices(l, r))
        
        e, N, v, op = self.e, self.N, self.v, self.op
        
        # calculate the answer for the query interval [l, r)
        left = l + N; right = r + N
        L = R = e
        while left < right:
            if left & 1: # self.v[left] is the right child
                L = op(L, v[left])
                left += 1
            if right & 1: # self.v[right-1] is the left child
                right -= 1
                R = op(v[right], R)
            left >>= 1; right >>= 1
        return op(L, R)
    
N, Q = map(int, input().split())
op = lambda x, y: x + y
apply = lambda x, f, l: x + f*l
comp = lambda f, g: f + g
e = 0
identity = 0
A = [e] * N
lpsg = LazyPropSegmentTree(A, op, apply, comp, e, identity)
ans = []
for _ in range(Q):
    t, *arg, = map(int, input().split())
    if t == 0:
        s, t, x = arg
        lpsg.update(s-1, t, x)
    else:
        s, t = arg
        ans.append(lpsg.fold(s-1, t))
print('\n'.join(map(str, ans)))

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline


class BIT():
    """区間加算、区間取得クエリをそれぞれO(logN)で答える
    add: 区間[l, r)にvalを加える
    get_sum: 区間[l, r)の和を求める
    l, rは0-indexed
    """
    def __init__(self, n):
        self.n = n
        self.bit0 = [0] * (n + 1)
        self.bit1 = [0] * (n + 1)

    def _add(self, bit, i, val):
        i = i + 1
        while i <= self.n:
            bit[i] += val
            i += i & -i

    def _get(self, bit, i):
        s = 0
        while i > 0:
            s += bit[i]
            i -= i & -i
        return s

    def add(self, l, r, val):
        """区間[l, r)にvalを加える"""
        self._add(self.bit0, l, -val * l)
        self._add(self.bit0, r,  val * r)
        self._add(self.bit1, l,  val)
        self._add(self.bit1, r, -val)

    def get_sum(self, l, r):
        """区間[l, r)の和を求める"""
        return self._get(self.bit0, r) + r * self._get(self.bit1, r) \
               - self._get(self.bit0, l) - l * self._get(self.bit1, l)


n, q = map(int, input().split())
query = [list(map(int, input().split())) for i in range(q)]
bit = BIT(n)

for i in range(q):
    if query[i][0] == 0:
        _, l, r, x = query[i]
        bit.add(l-1, r, x)
    else:
        _, l, r = query[i]
        print(bit.get_sum(l-1, r))

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-

import sys

def input(): return sys.stdin.readline().strip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
MOD = 10 ** 9 + 7

class BIT2:
    """ 区間加算BIT(区間加算・区間合計取得) """

    def __init__(self, N):
        N += 1
        self.N = N
        self.data0 = [0] * N
        self.data1 = [0] * N

    def _add(self, data, k, x):
        k += 1
        while k < self.N:
            data[k] += x
            k += k & -k

    def _get(self, data, k):
        k += 1
        s = 0
        while k:
            s += data[k]
            k -= k & -k
        return s

    def add(self, l, r, x):
        """ 区間[l,r)に値xを追加 """

        self._add(self.data0, l, -x*(l-1))
        self._add(self.data0, r, x*(r-1))
        self._add(self.data1, l, x)
        self._add(self.data1, r, -x)

    def query(self, l, r):
        """ 区間[l,r)の和を取得 """

        return self._get(self.data1, r-1) * (r-1) + self._get(self.data0, r-1) \
             - self._get(self.data1, l-1) * (l-1) - self._get(self.data0, l-1)

N, Q = MAP()
bit = BIT2(N+1)

for i in range(Q):
    cmd, *arg = MAP()
    if cmd == 0:
        s, t, x = arg
        bit.add(s, t+1, x)
    else:
        s, t = arg
        print(bit.query(s, t+1))

Submission status: Accepted

Solution code:
class BinaryIndexedTree():
    def __init__(self, n):
        self.n = n
        self.dat = [0] * (n + 1)

    def sum(self, i):
        s = 0
        while i:
            s += self.dat[i]
            i -= i & -i
        return s

    def add(self, i, x):
        while i <= self.n:
            self.dat[i] += x
            i += i & -i


N, Q = [int(_) for _ in input().split()]
Query = [input().split() for _ in range(Q)]
BIT0 = BinaryIndexedTree(N + 1)
BIT1 = BinaryIndexedTree(N + 1)
#sum'([0,p))=sum([0,p)) if p<a
#sum'([0,p))=sum([0,p))+p*x-(a-1)*x if a<=p<b
#sum'([0,p))=sum([0,p))+(b-(a-1))*x if b<=p
for query in Query:
    c, *array = query
    array = list(map(int, array))
    if c == '1':
        a, b = array
        a -= 1
        res = 0
        res += b * BIT1.sum(b) + BIT0.sum(b)
        res -= a * BIT1.sum(a) + BIT0.sum(a)
        print(res)
    else:
        a, b, x = array
        b += 1
        BIT1.add(a, x)
        BIT0.add(a, -(a - 1) * x)
        BIT1.add(b, -x)
        BIT0.add(b, (b - 1) * x)

Submission status: Accepted

Solution code:
class BinaryIndexedTree(object):
    def __init__(self, n: int) -> None:
        self.size = n
        self.bit = [0] * (self.size + 1)

    def add(self, i: int, v: int) -> None:
        while (i <= self.size):
            self.bit[i] += v
            i += (i & -i)  # i & -i picks the lowest 1 bit of i.

    def sum(self, i: int) -> int:
        s = 0
        while (i > 0):
            s += self.bit[i]
            i -= (i & -i)
        return s


class RangeQuery(object):
    def __init__(self, n: int) -> None:
        self.size = n
        self.bit1 = BinaryIndexedTree(n + 1)
        self.bit2 = BinaryIndexedTree(n + 1)

    def add(self, i: int, j: int, v: int) -> None:
        self.bit1.add(i, v * -i)
        self.bit1.add(j + 1, v * (j + 1))
        self.bit2.add(i, v)
        self.bit2.add(j + 1, -v)

    def sum(self, i: int, j: int) -> int:
        s = self.bit1.sum(j + 1) + (j + 1) * self.bit2.sum(j + 1)
        s -= self.bit1.sum(i) + i * self.bit2.sum(i)
        return s


if __name__ == "__main__":
    n, q = map(lambda x: int(x), input().split())
    rq = RangeQuery(n)

    for _ in range(q):
        com, *v = map(lambda x: int(x), input().split())
        if (0 == com):
            rq.add(v[0], v[1], v[2])
        else:
            print(rq.sum(v[0], v[1]))

Submission status: Accepted

Solution code:
class BIT:
    def __init__(self, n):
        self.size = n
        self.tree = [0]*(n+1)
    
    def Sum(self,i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
    
    def add(self,i,x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

class RangeUpdate:
    def __init__(self, n):
        self.p = BIT(n+1)
        self.q = BIT(n+1)
        
    def add(self,s,t,x):
        t+=1
        self.p.add(s,-x*s)
        self.p.add(t,x*t)
        self.q.add(s,x)
        self.q.add(t,-x)
        
    def Sum(self,s,t):
        t+=1
        return self.p.Sum(t) + self.q.Sum(t)*t-self.p.Sum(s)-self.q.Sum(s)*s
    
n, q = map(int, input().split())
tree = RangeUpdate(n)
for _ in range(q):
    a, *b = map(int,input().split())
    if a == 0:
        tree.add(b[0],b[1],b[2])
    else:
        print(tree.Sum(b[0],b[1]))

Submission status: Accepted

Solution code:
import sys
readline = sys.stdin.readline
write = sys.stdout.write
N, Q = map(int, readline().split())

data0 = [0]*(N+1)
data1 = [0]*(N+1)
def _add(data, k, x):
    while k <= N:
        data[k] += x
        k += k & -k
def add(l, r, x):
    _add(data0, l, -x*(l-1))
    _add(data0, r, x*(r-1))
    _add(data1, l, x)
    _add(data1, r, -x)

def _get(data, k):
    s = 0
    while k:
        s += data[k]
        k -= k & -k
    return s
def query(l, r):
    return _get(data1, r-1) * (r-1) + _get(data0, r-1) - _get(data1, l-1) * (l-1) - _get(data0, l-1)


ans = []
for q in range(Q):
    t, *cmd = map(int, readline().split())
    if t:
        s, t = cmd
        ans.append(str(query(s, t+1)))
    else:
        s, t, x = cmd
        add(s, t+1, x)
write("\n".join(ans))
write("\n")

Submission status: Accepted

Solution code:
#!/usr/bin/env python3
# DSL_2_G: RSQ and RAQ
# Range Add Query and Range Sum Query


class BinaryIndexedTree:
    def __init__(self, n):
        self.size = n
        self.bit = [0] * (self.size+1)

    def add(self, i, v):
        while i <= self.size:
            self.bit[i] += v
            i += (i & -i)

    def sum(self, i):
        s = 0
        while i > 0:
            s += self.bit[i]
            i -= (i & -i)
        return s


class RangeQuery:
    def __init__(self, n):
        self.size = n
        self.bit1 = BinaryIndexedTree(n+1)
        self.bit2 = BinaryIndexedTree(n+1)

    def add(self, i, j, v):
        self.bit1.add(i, v * -i)
        self.bit1.add(j+1, v * (j+1))
        self.bit2.add(i, v)
        self.bit2.add(j+1, -v)

    def sum(self, i, j):
        s = self.bit1.sum(j+1) + (j+1)*self.bit2.sum(j+1)
        s -= self.bit1.sum(i) + i*self.bit2.sum(i)
        return s


def run():
    n, q = [int(i) for i in input().split()]

    r = RangeQuery(n)

    for _ in range(q):
        com, *args = input().split()
        if com == '0':
            s, t, x = [int(i) for i in args]
            r.add(s, t, x)
        elif com == '1':
            s, t = [int(i) for i in args]
            print(r.sum(s, t))


if __name__ == '__main__':
    run()