AtCoder problem 037

C++ solution:
#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;



class RangeMax {

public:

	int size_ = 1;

	vector<long long> dat;



	void init(int sz) {

		while (size_ <= sz) size_ *= 2;

		dat.resize(size_ * 2, -(1LL << 60));

	}

	void update(int pos, long long x) {

		pos += size_;

		dat[pos] = x;

		while (pos >= 2) {

			pos >>= 1;

			dat[pos] = max(dat[pos * 2], dat[pos * 2 + 1]);

		}

	}

	long long query_(int l, int r, int a, int b, int u) {

		if (l <= a && b <= r) return dat[u];

		if (r <= a || b <= l) return -(1LL << 60);

		long long v1 = query_(l, r, a, (a + b) >> 1, u * 2);

		long long v2 = query_(l, r, (a + b) >> 1, b, u * 2 + 1);

		return max(v1, v2);

	}

	long long query(int l, int r) {

		return query_(l, r, 0, size_, 1);

	}

};



long long W, N;

long long L[1 << 18], R[1 << 18], V[1 << 18];

long long dp[509][10009];

RangeMax Z[509];



int main() {

	// Step #1. 入力

	cin >> W >> N;

	for (int i = 1; i <= N; i++) cin >> L[i] >> R[i] >> V[i];



	// Step #2. 初期化

	for (int i = 0; i <= N; i++) {

		for (int j = 0; j <= W; j++) dp[i][j] = -(1LL << 60);

		Z[i].init(W + 2);

	}

	dp[0][0] = 0;

	Z[0].update(0, 0);



	// Step #3. 動的計画法

	for (int i = 1; i <= N; i++) {

		for (int j = 0; j <= W; j++) dp[i][j] = dp[i - 1][j];

		for (int j = 0; j <= W; j++) {

			int cl = max(0, j - (int)R[i]), cr = max(0, j - (int)L[i] + 1);

			if (cl == cr) continue;

			long long val = Z[i - 1].query(cl, cr);

			if (val != -(1LL << 60)) {

				dp[i][j] = max(dp[i][j], val + V[i]);

			}

		}

		for (int j = 0; j <= W; j++) Z[i].update(j, dp[i][j]);

	}



	// Step #4. 出力

	if (dp[N][W] == -(1LL << 60)) cout << "-1" << endl;

	else cout << dp[N][W] << endl;

	return 0;

}





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