Problem:


Score : 100 points

Problem Statement

Consider a string of length N consisting of 0 and 1.
The score for the string is calculated as follows:

For each i (1 \leq i \leq M), a_i is added to the score if the string contains 1 at least once between the l_i-th and r_i-th characters (inclusive).

Find the maximum possible score of a string.

Constraints

All values in input are integers.

1 \leq N \leq 2 × 10^5

1 \leq M \leq 2 × 10^5

1 \leq l_i \leq r_i \leq N

|a_i| \leq 10^9

Input

Input is given from Standard Input in the following format:

N M
l_1 r_1 a_1
l_2 r_2 a_2
:
l_M r_M a_M

Output

Print the maximum possible score of a string.

Sample Input 1

5 3
1 3 10
2 4 -10
3 5 10

Sample Output 1

20

The score for 10001 is a_1 + a_3 = 10 + 10 = 20.

Sample Input 2

3 4
1 3 100
1 1 -10
2 2 -20
3 3 -30

Sample Output 2

90

The score for 100 is a_1 + a_2 = 100 + (-10) = 90.

Sample Input 3

1 1
1 1 -10

Sample Output 3

0

The score for 0 is 0.

Sample Input 4

1 5
1 1 1000000000
1 1 1000000000
1 1 1000000000
1 1 1000000000
1 1 1000000000

Sample Output 4

5000000000

The answer may not fit into a 32-bit integer type.

Sample Input 5

6 8
5 5 3
1 1 10
1 6 -8
3 6 5
3 4 9
5 5 -2
1 3 -6
4 6 -7

Sample Output 5

10

For example, the score for 101000 is a_2 + a_3 + a_4 + a_5 + a_7 = 10 + (-8) + 5 + 9 + (-6) = 10.



Sample input:
5 3
1 3 10
2 4 -10
3 5 10


Sample output:
20

Submission status: Accepted

Solution code:
import sys
input = lambda: sys.stdin.readline().rstrip()
class SegmentTree():
    def __init__(self, init, unitX, unitA, f, g, h):
        self.f = f # (X, X) -> X
        self.g = g # (X, A, i) -> X
        self.h = h # (A, A) -> A
        self.unitX = unitX
        self.unitA = unitA
        self.f = f
        if type(init) == int:
            self.n = init
            # self.n = 1 << (self.n - 1).bit_length()
            self.X = [unitX] * (self.n * 2)
            self.size = [1] * (self.n * 2)
        else:
            self.n = len(init)
            # self.n = 1 << (self.n - 1).bit_length()
            self.X = [unitX] * self.n + init + [unitX] * (self.n - len(init))
            self.size = [0] * self.n + [1] * len(init) + [0] * (self.n - len(init))
            for i in range(self.n-1, 0, -1):
                self.X[i] = self.f(self.X[i*2], self.X[i*2|1])
    
        for i in range(self.n - 1, 0, -1):
            self.size[i] = self.size[i*2] + self.size[i*2|1]
        
        self.A = [unitA] * (self.n * 2)
        
    def update(self, i, x):
        i += self.n
        self.X[i] = x
        i >>= 1
        while i:
            self.X[i] = self.f(self.X[i*2], self.X[i*2|1])
            i >>= 1
    
    def calc(self, i):
        return self.g(self.X[i], self.A[i], self.size[i])
    
    def calc_above(self, i):
        i >>= 1
        while i:
            self.X[i] = self.f(self.calc(i*2), self.calc(i*2|1))
            i >>= 1
    
    def propagate(self, i):
        self.X[i] = self.g(self.X[i], self.A[i], self.size[i])
        self.A[i*2] = self.h(self.A[i*2], self.A[i])
        self.A[i*2|1] = self.h(self.A[i*2|1], self.A[i])
        self.A[i] = self.unitA
        
    def propagate_above(self, i):
        H = i.bit_length()
        for h in range(H, 0, -1):
            self.propagate(i >> h)
    
    def propagate_all(self):
        for i in range(1, self.n):
            self.propagate(i)
    
    def getrange(self, l, r):
        l += self.n
        r += self.n
        l0, r0 = l // (l & -l), r // (r & -r) - 1
        self.propagate_above(l0)
        self.propagate_above(r0)
        
        al = self.unitX
        ar = self.unitX
        while l < r:
            if l & 1:
                al = self.f(al, self.calc(l))
                l += 1
            if r & 1:
                r -= 1
                ar = self.f(self.calc(r), ar)
            l >>= 1
            r >>= 1
        return self.f(al, ar)
    
    def getvalue(self, i):
        i += self.n
        self.propagate_above(i)
        return self.calc(i)
    
    def operate_range(self, l, r, a):
        l += self.n
        r += self.n
        l0, r0 = l // (l & -l), r // (r & -r) - 1
        self.propagate_above(l0)
        self.propagate_above(r0)
        while l < r:
            if l & 1:
                self.A[l] = self.h(self.A[l], a)
                l += 1
            if r & 1:
                r -= 1
                self.A[r] = self.h(self.A[r], a)
            l >>= 1
            r >>= 1
        
        self.calc_above(l0)
        self.calc_above(r0)
    
    def debug(self):
        print("self.n =", self.n)
        deX = []
        deA = []
        deS = []
        a, b = self.n, self.n * 2
        while b:
            deX.append(self.X[a:b])
            deA.append(self.A[a:b])
            deS.append(self.size[a:b])
            a, b = a//2, a
        print("--- debug ---")
        for d in deX[::-1]:
            print(d)
        print("--- ---")
        for d in deA[::-1]:
            print(d)
        print("--- ---")
        for d in deS[::-1]:
            print(d)
        print("--- ---")

f = max
g = lambda x, a, s: a + x
h = lambda a, b: a + b
N, M = map(int, input().split())

L = [[] for _ in range(N + 1)]
for _ in range(M):
    l, r, a = map(int, input().split())
    L[r].append((l-1, a))

st = SegmentTree(N+10, 0, 0, f, g, h)
for r in range(N + 1):
    m = st.X[1]
    for l, a in L[r]:
        st.operate_range(l, r, a)
    
    st.operate_range(r, r+1, st.X[1])
    
print(st.X[1])

Submission status: Accepted

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

def I(): return int(input())
def MI(): return map(int, input().split())
def LI(): return list(map(int, input().split()))

def main():
    mod=10**9+7
    N,M=MI()

    class Lazysegtree:
        #RAQ
        def __init__(self, A, intv, initialize = True, segf = min):
            #区間は 1-indexed で管理
            self.N = len(A)
            self.N0 = 2**(self.N-1).bit_length()
            self.intv = intv
            self.segf = segf
            self.lazy = [0]*(2*self.N0)
            if initialize:
                self.data = [intv]*self.N0 + A + [intv]*(self.N0 - self.N)
                for i in range(self.N0-1, 0, -1):
                    self.data[i] = self.segf(self.data[2*i], self.data[2*i+1]) 
            else:
                self.data = [intv]*(2*self.N0)

        def _ascend(self, k):
            k = k >> 1
            c = k.bit_length()
            for j in range(c):
                idx = k >> j
                self.data[idx] = self.segf(self.data[2*idx], self.data[2*idx+1]) \
                + self.lazy[idx]
                
        def _descend(self, k):
            k = k >> 1
            idx = 1
            c = k.bit_length()
            for j in range(1, c+1):
                idx = k >> (c - j)
                ax = self.lazy[idx]
                if not ax:
                    continue
                self.lazy[idx] = 0
                self.data[2*idx] += ax
                self.data[2*idx+1] += ax
                self.lazy[2*idx] += ax
                self.lazy[2*idx+1] += ax
        
        def update(self, k, x):
            k = k + self.N0
            self.data[k] = x
            self._ascend(k)
        
        def query(self, l, r):
            L = l+self.N0
            R = r+self.N0
            Li = L//(L & -L)
            Ri = R//(R & -R)
            self._descend(Li)
            self._descend(Ri - 1)
            
            s = self.intv                                                              
            while L < R:
                if R & 1:
                    R -= 1
                    s = self.segf(s, self.data[R])
                if L & 1:
                    s = self.segf(s, self.data[L])
                    L += 1
                L >>= 1
                R >>= 1
            return s
        
        def add(self, l, r, x):
            L = l+self.N0
            R = r+self.N0

            Li = L//(L & -L)
            Ri = R//(R & -R)
            
            while L < R :
                if R & 1:
                    R -= 1
                    self.data[R] += x
                    self.lazy[R] += x
                if L & 1:
                    self.data[L] += x
                    self.lazy[L] += x
                    L += 1
                L >>= 1
                R >>= 1
            
            self._ascend(Li)
            self._ascend(Ri-1)
            
    sst=Lazysegtree([0]*(N+1), 0, True, max)
            
    la=[[]for _ in range(N+1)]
    
    for i in range(M):
        l,r,a=MI()
        la[r].append([l,a])
    
    
    #sst[i]はi桁目がビットの立っている最右である時のmax
    #lrのクエリはrまで来た時に，範囲内に加算
    
 
    for i in range(1,N+1):
        temp=sst.query(0,i)
        sst.add(i,i+1,temp)#とりあえず，[0,i)の最大値を入れておく
        
        for l,a in la[i]:
            sst.add(l,i+1,a)
        
            
    print(sst.query(0,N+1))

main()

Submission status: Accepted

Solution code:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines


class LazySegTree:
    data_unit = 0
    data_f = max
    operator_unit = 0
    
    @classmethod
    def operator_f(cls, x, y):
      return x + y
    
    @classmethod
    def operate(cls, x, y):
      return x + y
    
    def __init__(self, N):
        self.N = N
        self.H = (self.N - 1).bit_length()
        self.data = [self.data_unit] * (N + N)
        self.lazy = [self.operator_unit] * (N + N)

    def build(self, raw_data):
        data = self.data
        f = self.data_f
        N = self.N
        data[N:] = raw_data[:]
        for i in range(N - 1, 0, -1):
            data[i] = f(data[i << 1], data[i << 1 | 1])

    def reflect(self, k):
        x = self.lazy[k]
        if x == self.operator_unit:
            return self.data[k]
        else:
            return self.operate(self.data[k], x)

    def propagate(self, k):
        lazy = self.lazy
        if lazy[k] == self.operator_unit:
            return
        h = self.operator_f
        lazy[k << 1] = h(lazy[k << 1], lazy[k])
        lazy[k << 1 | 1] = h(lazy[k << 1 | 1], lazy[k])
        self.data[k] = self.reflect(k)
        self.lazy[k] = self.operator_unit

    def thrust(self, k):
        for i in range(self.H, 0, -1):
            self.propagate(k >> i)

    def recalc(self, k):
        data = self.data
        f = self.data_f
        while k > 1:
            k >>= 1
            data[k] = f(self.reflect(k << 1), self.reflect(k << 1 | 1))

    def update(self, L, R, x):
        lazy = self.lazy
        h = self.operator_f
        L0 = L = L + self.N
        R0 = R = R + self.N
        self.thrust(L0)
        self.thrust(R0 - 1)
        while L < R:
            if L & 1:
                lazy[L] = h(lazy[L], x)
                L += 1
            if R & 1:
                R -= 1
                lazy[R] = h(lazy[R], x)
            L >>= 1
            R >>= 1
        self.recalc(L0)
        self.recalc(R0 - 1)

    def set_val(self, i, x):
        i += self.N
        self.thrust(i)
        self.data[i] = x
        self.lazy[i] = self.operator_unit
        self.recalc(i)

    def fold(self, L, R):
        f = self.data_f
        L += self.N
        R += self.N
        self.thrust(L)
        self.thrust(R - 1)
        vl = self.data_unit
        vr = self.data_unit
        while L < R:
            if L & 1:
                vl = f(vl, self.reflect(L))
                L += 1
            if R & 1:
                R -= 1
                vr = f(self.reflect(R), vr)
            L >>= 1
            R >>= 1
        return f(vl, vr)

N, M = map(int, readline().split())
R_to_LA = [[] for _ in range(N + 1)]
m = map(int, read().split())
for L, R, A in zip(m, m, m):
    R_to_LA[R].append((L, A))

seg = LazySegTree(N+1)
 
for R in range(1, N + 1):
    x = seg.data[1]
    seg.update(R, R + 1, x)
    for L, A in R_to_LA[R]:
        seg.update(L, R + 1, A)
print(seg.fold(0, N+1))

Submission status: Accepted

Solution code:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines


class LazySegmentTree:
    """ range add and range max"""

    def __init__(self, A):
        INF = 10 ** 18
        self.unit = -INF
        self.N = len(A)
        self.H = (self.N - 1).bit_length()
        self.W = 1 << self.H
        self.lazy = [0] * (2 * self.W)
        self.build(A)

    def build(self, A):
        W = self.W
        data = [self.unit] * (2 * W)
        for i, x in enumerate(A):
            data[W + i] = x
        for i in range(W - 1, 0, -1):
            data[i] = max(data[i << 1], data[i << 1 | 1])
        self.data = data

    def apply(self, p, value):
        self.data[p] += value
        self.lazy[p] += value

    def build_local(self, i):
        while i > 1:
            i >>= 1
            self.data[i] = max(self.data[i << 1], self.data[i << 1 | 1]) + self.lazy[i]

    def propagate(self, p):
        for s in range(self.H, 0, -1):
            i = p >> s
            x = self.lazy[i]
            self.apply(i << 1, x)
            self.apply(i << 1 | 1, x)
            self.lazy[i] = 0

    def range_add(self, L, R, x):
        """ add x to [L,R) """
        L += self.W
        R += self.W
        L0 = L
        R0 = R
        while L < R:
            if L & 1:
                self.apply(L, x)
                L += 1
            if R & 1:
                R -= 1
                self.apply(R, x)
            L >>= 1
            R >>= 1
        self.build_local(L0)
        self.build_local(R0 - 1)

    def range_max(self, L, R):
        """ max of [L,R) """
        L += self.W
        R += self.W
        self.propagate(L)
        self.propagate(R - 1)
        ret = self.unit
        while L < R:
            if L & 1:
                x = self.data[L]
                if ret < x:
                    ret = x
                L += 1
            if R & 1:
                R -= 1
                x = self.data[R]
                if ret < x:
                    ret = x
            L >>= 1
            R >>= 1


N, M = map(int, readline().split())
R_to_LA = [[] for _ in range(N + 1)]
m = map(int, read().split())
for L, R, A in zip(m, m, m):
    R_to_LA[R].append((L, A))

seg = LazySegmentTree([0] * (N + 1))

for R in range(1, N + 1):
    x = seg.data[1]
    seg.range_add(R, R + 1, x)
    for L, A in R_to_LA[R]:
        seg.range_add(L, R + 1, A)
print(seg.data[1])

Submission status: Accepted

Solution code:
import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__

class RAQ_RMQ:
    def __init__(self, n, F=min, e=float("inf"), fill=None):
        self.n = n
        self.n0 = 2**(n-1).bit_length()
        self.e = e
        self.F = F
        self.lazy = [0]*(2*self.n0)
        if fill is None:
            fill = e
        self.data = [fill]*(2*self.n0)

    def construct(self, a):
        for i, x in enumerate(a):
            self.data[i+self.n0] = x
        for i in range(self.n0-1, 0, -1):
            self.data[i] = self.F(self.data[2*i], self.data[2*i+1])

    def bottomup(self, i):
        i += self.n0
        k = i//(i & -i)
        c = k.bit_length()
        for j in range(c-1):
            k >>= 1
            self.data[k] = self.F(self.data[2*k], self.data[2*k+1]) + self.lazy[k]

    def topdown(self, i):
        i += self.n0
        k = i//(i & -i)
        c = k.bit_length()
        for j in range(c-1):
            idx = k >> (c - j - 1)
            ax = self.lazy[idx]
            if not ax:
                continue
            self.lazy[idx] = 0
            self.data[2*idx] += ax
            self.data[2*idx+1] += ax
            self.lazy[2*idx] += ax
            self.lazy[2*idx+1] += ax

    def query(self, l, r):
        self.topdown(l)
        self.topdown(r)
        L = l+self.n0
        R = r+self.n0

        s = self.e
        while L < R:
            if R & 1:
                R -= 1
                s = self.F(s, self.data[R])
            if L & 1:
                s = self.F(s, self.data[L])
                L += 1
            L >>= 1
            R >>= 1
        return s

    def add(self, l, r, x):
        L = l+self.n0
        R = r+self.n0

        while L < R :
            if R & 1:
                R -= 1
                self.data[R] += x
                self.lazy[R] += x
            if L & 1:
                self.data[L] += x
                self.lazy[L] += x
                L += 1
            L >>= 1
            R >>= 1

        self.bottomup(l)
        self.bottomup(r)

n,m = map(int, input().split())

memo = [[] for i in range(n+2)]
for i in range(m):
    l,r,a = map(int, input().split())
    memo[l].append((l,a))
    memo[r+1].append((l,-a))

seg = RAQ_RMQ(n+2, F=max, e=-float("inf"), fill=0)

for i in range(1, n+2):
    for j, a in memo[i]:
        seg.add(0, j, a)
    tmp = seg.query(0, i)
    seg.add(i, i+1, tmp)

ans = seg.query(0, n+1)
print(ans)

Submission status: Accepted

Solution code:
import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__

class RAQ_RMQ:
    def __init__(self, n, a=None, F=min, e=float("inf")):
        self.n = n
        self.n0 = 2**(n-1).bit_length()
        self.e = e
        self.F = F
        self.lazy = [0]*(2*self.n0)
        if a is None:
            self.data = [e]*(2*self.n0)
        else:
            self.data = [0]*(2*self.n0)
            self.construct(a)

    def construct(self, a):
        for i, x in enumerate(a):
            self.data[i+self.n0] = x
        for i in range(self.n0-1, 0, -1):
            self.data[i] = self.F(self.data[2*i], self.data[2*i+1])

    def bottomup(self, i):
        i += self.n0
        k = i//(i & -i)
        c = k.bit_length()
        for j in range(c-1):
            k >>= 1
            self.data[k] = self.F(self.data[2*k], self.data[2*k+1]) + self.lazy[k]

    def topdown(self, i):
        i += self.n0
        k = i//(i & -i)
        c = k.bit_length()
        for j in range(c-1):
            idx = k >> (c - j - 1)
            ax = self.lazy[idx]
            if not ax:
                continue
            self.lazy[idx] = 0
            self.data[2*idx] += ax
            self.data[2*idx+1] += ax
            self.lazy[2*idx] += ax
            self.lazy[2*idx+1] += ax

    def query(self, l, r):
        self.topdown(l)
        self.topdown(r)
        L = l+self.n0
        R = r+self.n0

        s = self.e
        while L < R:
            if R & 1:
                R -= 1
                s = self.F(s, self.data[R])
            if L & 1:
                s = self.F(s, self.data[L])
                L += 1
            L >>= 1
            R >>= 1
        return s

    def add(self, l, r, x):
        L = l+self.n0
        R = r+self.n0

        while L < R :
            if R & 1:
                R -= 1
                self.data[R] += x
                self.lazy[R] += x
            if L & 1:
                self.data[L] += x
                self.lazy[L] += x
                L += 1
            L >>= 1
            R >>= 1

        self.bottomup(l)
        self.bottomup(r)

n,m = map(int, input().split())

memo = [[] for i in range(n+2)]
for i in range(m):
    l,r,a = map(int, input().split())
    memo[l].append((l,a))
    memo[r+1].append((l,-a))

seg = RAQ_RMQ(n+2, a=[0]*(n+2), F=max, e=-float("inf"))

for i in range(1, n+2):
    for j, a in memo[i]:
        seg.add(0, j, a)
    tmp = seg.query(0, i)
    seg.add(i, i+1, tmp)

ans = seg.query(0, n+1)
print(ans)

Submission status: Accepted

Solution code:
import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__

class RAQ_RMQ:
    def __init__(self, n, F=min, e=float("inf")):
        self.n = n
        self.n0 = 2**(n-1).bit_length()
        self.e = e
        self.F = F
        self.lazy = [0]*(2*self.n0)
        self.data = [e]*(2*self.n0)

    def construct(self, a):
        for i, x in enumerate(a):
            self.data[i+self.n0] = x
        for i in range(self.n0-1, 0, -1):
            self.data[i] = self.F(self.data[2*i], self.data[2*i+1])

    def bottomup(self, i):
        i += self.n0
        k = i//(i & -i)
        c = k.bit_length()
        for j in range(c-1):
            k >>= 1
            self.data[k] = self.F(self.data[2*k], self.data[2*k+1]) + self.lazy[k]

    def topdown(self, i):
        i += self.n0
        k = i//(i & -i)
        c = k.bit_length()
        for j in range(c-1):
            idx = k >> (c - j - 1)
            ax = self.lazy[idx]
            if not ax:
                continue
            self.lazy[idx] = 0
            self.data[2*idx] += ax
            self.data[2*idx+1] += ax
            self.lazy[2*idx] += ax
            self.lazy[2*idx+1] += ax

    def query(self, l, r):
        self.topdown(l)
        self.topdown(r)
        L = l+self.n0
        R = r+self.n0

        s = self.e
        while L < R:
            if R & 1:
                R -= 1
                s = self.F(s, self.data[R])
            if L & 1:
                s = self.F(s, self.data[L])
                L += 1
            L >>= 1
            R >>= 1
        return s

    def add(self, l, r, x):
        L = l+self.n0
        R = r+self.n0

        while L < R :
            if R & 1:
                R -= 1
                self.data[R] += x
                self.lazy[R] += x
            if L & 1:
                self.data[L] += x
                self.lazy[L] += x
                L += 1
            L >>= 1
            R >>= 1

        self.bottomup(l)
        self.bottomup(r)

n,m = map(int, input().split())
memo = [[] for i in range(n+2)]
for i in range(m):
    l,r,a = map(int, input().split())
    memo[l].append((l,a))
    memo[r+1].append((l,-a))

seg = RAQ_RMQ(n+2, F=max, e=-float("inf"))
seg.construct([0]*(n+2))
for i in range(1, n+2):
    for j, a in memo[i]:
        seg.add(0, j, a)
    tmp = seg.query(0, i)
    seg.add(i, i+1, tmp)
ans = seg.query(0, n+1)
print(ans)

Submission status: Accepted

Solution code:
import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__

class RAQ_RMQ:
    def __init__(self, n, F=min, e=float("inf")):
        self.n = n
        self.n0 = 2**(n-1).bit_length()
        self.e = e
        self.F = F
        self.lazy = [0]*(2*self.n0)
        self.data = [e]*(2*self.n0)

    def construct(self, a):
        for i, x in enumerate(a):
            self.data[i+self.n0] = x
        for i in range(self.n0-1, 0, -1):
            self.data[i] = self.F(self.data[2*i], self.data[2*i+1])

    def bottomup(self, i):
        i += self.n0
        k = i//(i & -i)
        c = k.bit_length()
        for j in range(c-1):
            k >>= 1
            self.data[k] = self.F(self.data[2*k], self.data[2*k+1]) + self.lazy[k]

    def topdown(self, i):
        i += self.n0
        k = i//(i & -i)
        c = k.bit_length()
        for j in range(c-1):
            idx = k >> (c - j - 1)
            ax = self.lazy[idx]
            if not ax:
                continue
            self.lazy[idx] = 0
            self.data[2*idx] += ax
            self.data[2*idx+1] += ax
            self.lazy[2*idx] += ax
            self.lazy[2*idx+1] += ax

    def query(self, l, r):
        self.topdown(l)
        self.topdown(r)
        L = l+self.n0
        R = r+self.n0

        s = -float("inf")
        while L < R:
            if R & 1:
                R -= 1
                s = self.F(s, self.data[R])
            if L & 1:
                s = self.F(s, self.data[L])
                L += 1
            L >>= 1
            R >>= 1
        return s

    def add(self, l, r, x):
        L = l+self.n0
        R = r+self.n0

        while L < R :
            if R & 1:
                R -= 1
                self.data[R] += x
                self.lazy[R] += x
            if L & 1:
                self.data[L] += x
                self.lazy[L] += x
                L += 1
            L >>= 1
            R >>= 1

        self.bottomup(l)
        self.bottomup(r)

n,m = map(int, input().split())
memo = [[] for i in range(n+2)]
for i in range(m):
    l,r,a = map(int, input().split())
    memo[l].append((l,a))
    memo[r+1].append((l,-a))

seg = RAQ_RMQ(n+2, F=max, e=0)
for i in range(1, n+2):
    for j, a in memo[i]:
        seg.add(0, j, a)
    tmp = seg.query(0, i)
    seg.add(i, i+1, tmp)
ans = seg.query(0, n+1)
print(ans)

Submission status: Accepted

Solution code:
import sys
class Lazysegtree:
    #RAQ
    def __init__(self, A, intv, initialize = True, segf = min):
        #区間は 1-indexed で管理
        self.N = len(A)
        self.N0 = 2**(self.N-1).bit_length()
        self.intv = intv
        self.segf = segf
        self.lazy = [0]*(2*self.N0)
        if initialize:
            self.data = [intv]*self.N0 + A + [intv]*(self.N0 - self.N)
            for i in range(self.N0-1, 0, -1):
                self.data[i] = self.segf(self.data[2*i], self.data[2*i+1]) 
        else:
            self.data = [intv]*(2*self.N0)

    def _ascend(self, k):
        k = k >> 1
        c = k.bit_length()
        for j in range(c):
            idx = k >> j
            self.data[idx] = self.segf(self.data[2*idx], self.data[2*idx+1]) \
            + self.lazy[idx]
            
    def _descend(self, k):
        k = k >> 1
        idx = 1
        c = k.bit_length()
        for j in range(1, c+1):
            idx = k >> (c - j)
            ax = self.lazy[idx]
            if not ax:
                continue
            self.lazy[idx] = 0
            self.data[2*idx] += ax
            self.data[2*idx+1] += ax
            self.lazy[2*idx] += ax
            self.lazy[2*idx+1] += ax
    
    def update(self, k, x):
        k = k + self.N0
        self.data[k] = x
        self._ascend(k)
    
    def query(self, l, r):
        L = l+self.N0
        R = r+self.N0
        Li = L//(L & -L)
        Ri = R//(R & -R)
        self._descend(Li)
        self._descend(Ri - 1)
        
        s = self.intv                                                              
        while L < R:
            if R & 1:
                R -= 1
                s = self.segf(s, self.data[R])
            if L & 1:
                s = self.segf(s, self.data[L])
                L += 1
            L >>= 1
            R >>= 1
        return s
    
    def add(self, l, r, x):
        L = l+self.N0
        R = r+self.N0

        Li = L//(L & -L)
        Ri = R//(R & -R)
        
        while L < R :
            if R & 1:
                R -= 1
                self.data[R] += x
                self.lazy[R] += x
            if L & 1:
                self.data[L] += x
                self.lazy[L] += x
                L += 1
            L >>= 1
            R >>= 1
        
        self._ascend(Li)
        self._ascend(Ri-1)

N, M = map(int, input().split())
LA = [[] for _ in range(N)]
for _ in range(M):
    l, r, a = map(int, sys.stdin.readline().split())
    LA[r-1].append((l-1, a))

dp = Lazysegtree([0]*(N+1), -10**16, True, max)

for i in range(N):
    res = 0
    t = dp.data[1]
    for l, a in LA[i]:
        res += a
        dp.add(l, i, a)
    dp.add(i, i+1, res + t)
print(dp.data[1])

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
N, M = map(int, input().split())

N0 = 2**((N+1).bit_length())
INF = 10**18
data = [0]*(2*N0)
lazy = [0]*(2*N0)

def gindex(l, r):
    L = l + N0; R = r + N0
    lm = (L // (L & -L)) >> 1
    rm = (R // (R & -R)) >> 1
    while L < R:
        if R <= rm:
            yield R
        if L <= lm:
            yield L
        L >>= 1; R >>= 1
    while L:
        yield L
        L >>= 1

def propagates(*ids):
    for i in reversed(ids):
        v = lazy[i-1]
        if not v:
            continue
        lazy[2*i-1] += v; lazy[2*i] += v
        data[2*i-1] += v; data[2*i] += v
        lazy[i-1] = 0
        
def update(l, r, x):
    L = N0 + l; R = N0 + r
    while L < R:
        if R & 1:
            R -= 1
            lazy[R-1] += x; data[R-1] += x
        if L & 1:
            lazy[L-1] += x; data[L-1] += x
            L += 1
        L >>= 1; R >>= 1

    for i in gindex(l, r):
        data[i-1] = max(data[2*i-1], data[2*i]) + lazy[i-1]

def update2(k, x):
    k += N0-1
    data[k] = x
    while k >= 0:
        k = (k - 1) // 2
        data[k] = max(data[2*k+1], data[2*k+2])

def query(l, r):
    propagates(*gindex(l, r))
    L = N0 + l; R = N0 + r
    s = -INF
    while L < R:
        if R & 1:
            R -= 1
            s = max(s, data[R-1])
        if L & 1:
            s = max(s, data[L-1])
            L += 1
        L >>= 1; R >>= 1
    return s

xs = [0]*(N+1)
ys = [[] for _ in range(N+1)]
for _ in range(M):
    l, r, a = map(int, input().split())
    xs[l] += a
    ys[r].append((l,a))

for i in range(1, N+1):
    update(0,i,xs[i])
    update2(i, query(0, i))
    for l, a in ys[i]:
        update(0, l, -a)
print(query(0,N+1))

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
N, M = map(int, input().split())

N0 = 2**((N+1).bit_length())
INF = 10**18
data = [0]*(2*N0)
lazy = [0]*(2*N0)

def gindex(l, r):
    L = l + N0; R = r + N0
    lm = (L // (L & -L)) >> 1
    rm = (R // (R & -R)) >> 1
    while L < R:
        if R <= rm:
            yield R
        if L <= lm:
            yield L
        L >>= 1; R >>= 1
    while L:
        yield L
        L >>= 1

def propagates(*ids):
    for i in reversed(ids):
        v = lazy[i-1]
        if not v:
            continue
        lazy[2*i-1] += v; lazy[2*i] += v
        data[2*i-1] += v; data[2*i] += v
        lazy[i-1] = 0
        
def update(l, r, x):
    L = N0 + l; R = N0 + r
    while L < R:
        if R & 1:
            R -= 1
            lazy[R-1] += x; data[R-1] += x
        if L & 1:
            lazy[L-1] += x; data[L-1] += x
            L += 1
        L >>= 1; R >>= 1

    for i in gindex(l, r):
        data[i-1] = max(data[2*i-1], data[2*i]) + lazy[i-1]

def update2(k, x):
    k += N0-1
    data[k] = x
    while k >= 0:
        k = (k - 1) // 2
        data[k] = max(data[2*k+1], data[2*k+2])

def query(l, r):
    propagates(*gindex(l, r))
    L = N0 + l; R = N0 + r
    s = -INF
    while L < R:
        if R & 1:
            R -= 1
            s = max(s, data[R-1])
        if L & 1:
            s = max(s, data[L-1])
            L += 1
        L >>= 1; R >>= 1
    return s

xs = [0]*(N+1)
ys = [[] for _ in range(N+1)]
for _ in range(M):
    l, r, a = map(int, input().split())
    xs[l] += a
    ys[r].append((l,a))

rs = [0]*(N+1)
for i in range(1, N+1):
    #[0,i)にxs[i]を加算
    update(0,i,xs[i])
    r = query(0, i)
    update2(i, r)
    rs[i] = r
    for l, a in ys[i]:
        update(0, l, -a)
print(max(rs))