AtCoder problem 037

C++ solution:


Python solution: import sys
from collections import defaultdict, Counter, deque
from itertools import permutations, combinations, product, combinations_with_replacement, groupby, accumulate
import operator
from math import sqrt, gcd, factorial
# from math import isqrt, prod,comb  # python3.8用(notpypy)
#from bisect import bisect_left,bisect_right
#from functools import lru_cache,reduce
#from heapq import heappush,heappop,heapify,heappushpop,heapreplace
#import numpy as np
#import networkx as nx
#from networkx.utils import UnionFind
#from numba import njit, b1, i1, i4, i8, f8
#from scipy.sparse import csr_matrix
#from scipy.sparse.csgraph import shortest_path, floyd_warshall, dijkstra, bellman_ford, johnson, NegativeCycleError
# numba例 @njit(i1(i4[:], i8[:, :]),cache=True) 引数i4配列、i8 2次元配列,戻り値i1
def input(): return sys.stdin.readline().rstrip()
def divceil(n, k): return 1+(n-1)//k  # n/kの切り上げを返す
def yn(hantei, yes='Yes', no='No'): print(yes if hantei else no)


class SparceTable:
    def __init__(self, A, op=min, e=10**10):
        self.n = len(A)
        self.op = op
        self.e = e
        self.table = [None]*(len(A).bit_length())  # [i, i+2^k)のop
        self.table[0] = A
        pre_table = A
        k = 0
        for k in range(len(A).bit_length()-1):
            pre_table = self.table[k]
            self.table[k+1] = [op(pre_table[i], pre_table[i+(1 << k)])
                               for i in range(len(pre_table)-(1 << k))]
            k += 1

    # [l, r)のop
    def query(self, l, r):
        l = min(max(0, l),self.n)
        r = min(max(0, r),self.n)
        if l == r:
            return self.e

        k = (r-l).bit_length()-1
        return self.op(self.table[k][l], self.table[k][r-(1 << k)])


def main():
    mod = 10**9+7
    mod2 = 998244353
    w, n = map(int, input().split())
    c=[-10**15]*(w+1)
    c[0]=0
    dp = SparceTable(c, op=max, e=-10**15)
    for _ in range(n):
        l, r, v = map(int, input().split())
        newdp=[0]*(w+1)
        for i in range(w+1):
            newdp[i]=max(dp.query(i-r,i-l+1)+v,dp.query(i,i+1))
        dp=SparceTable(newdp,op=max,e=-10**15)
        #print(newdp)
    print(max(-1,dp.query(w,w+1)))


if __name__ == '__main__':
    main()



Kuin solution: func main()
	var w: int :: cui@inputInt()
	var n: int :: cui@inputInt()
	var l: []int :: #[n]int
	var r: []int :: #[n]int
	var v: []int :: #[n]int
	for i(0, n - 1)
		do l[i] :: cui@inputInt()
		do r[i] :: cui@inputInt()
		do v[i] :: cui@inputInt()
	end for
	
	var dp: [][]int :: #[n + 1, w + 1]int
	for j(0, w)
		do dp[0][j] :: lib@intMin
	end for
	do dp[0][0] :: 0
	for i(0, n - 1)
		var seg: @SegmentTree :: (#@SegmentTree).init(w + 1)
		for j(0, w)
			do seg.update(j, dp[i][j])
		end for
		for j(0, w)
			var val: int :: seg.query([j - r[i], 0].max(), j - l[i] + 1)
			do dp[i + 1][j] :: lib@max(dp[i][j], val + v[i])
		end for
	end for
	
	var ans: int :: [dp[n][w], -1].max()
	do cui@print("\{ans}\n")
end func

class SegmentTree()
	const invalid: int :: lib@intMin
	var size: int
	var node: []int
	+func init(n: int): SegmentTree
		do me.size :: 1
		while(me.size < n)
			do me.size :* 2
		end while
		do me.node :: #[2 * me.size]int
		for i(0, 2 * me.size - 1)
			do me.node[i] :: invalid
		end for
		ret me
	end func
	+func update(idx: int, val: int)
		do idx :+ me.size - 1
		do me.node[idx] :: val
		while(idx > 0)
			do idx :: (idx - 1) / 2
			do me.node[idx] :: lib@max(me.node[2 * idx + 1], me.node[2 * idx + 2])
		end while
	end func
	+func query(a: int, b: int): int
		ret me.querySub(a, b, 0, 0, me.size)
	end func
	func querySub(a: int, b: int, k: int, l: int, r: int): int
		if(b <= l | r <= a)
			ret invalid
		end if
		if(a <= l & r <= b)
			ret me.node[k]
		end if
		var vl: int :: me.querySub(a, b, 2 * k + 1, l, (l + r) / 2)
		var vr: int :: me.querySub(a, b, 2 * k + 2, (l + r) / 2, r)
		ret lib@max(vl, vr)
	end func
	+*func toStr(): []char
		var padding: int :: 1
		while(padding <= me.size)
			do padding :* 2
		end while
		do padding :- 1
		var res: []char :: ""
		var s: int :: 0
		var e: int :: 0
		var n: int :: 1
		const digit: int :: 6
		var fmt: []char :: " \{digit}d"
		var strInf: []char :: " ".repeat(digit - 3) ~ "inf"
		while(padding > 0)
			do padding :/ 2
			for i(s, e)
				do res :~ " ".repeat((digit + 1) * padding)
				do res :~ "\{me.node[i] = invalid ?(strInf, me.node[i].toStrFmt(fmt))}|"
			end for
			do res :~ "\n"
			do n :* 2
			do s :: e + 1
			do e :: s + n - 1
		end while
		ret res
	end func
end class