1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| #include <bits/stdc++.h>
#define int long long using namespace std;
using i64 = long long; using u64 = unsigned long long; using u32 = unsigned;
using u128 = unsigned __int128; using i128 = __int128; using ld = long double;
signed main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr);
int n; cin >> n; vector<int> w(n + 1), v(n + 1); for (int i = 1; i <= n; i++) { cin >> w[i] >> v[i]; } int q; cin >> q; vector<array<int, 3>> query; for (int i = 1; i <= q; i++) { int l, r, c; cin >> l >> r >> c; query.push_back({l, r, c}); }
vector<int> ans(q); constexpr int K = 500; vector dpl(n + 1, vector<int>(K + 1)), dpr(n + 1, vector<int>(K + 1)); auto update = [&](const vector<int> &ndp, vector<int> &dp, int i) { for (int j = 0; j <= K; j++) { dp[j] = ndp[j]; if (j >= w[i]) { dp[j] = max(dp[j], ndp[j - w[i]] + v[i]); } } }; auto solve = [&](auto solve, int l, int r, const vector<int> &qid) -> void { if (l == r) { for (auto i : qid) { auto [nl, nr, nc] = query[i]; assert(nl == l && nr == r); ans[i] = nc >= w[l] ? v[l] : 0; } return; } int m = l + (r - l) / 2; fill(dpl[m + 1].begin(), dpl[m + 1].end(), 0); fill(dpr[m].begin(), dpr[m].end(), 0); for (int i = m; i >= l; i--) { update(dpl[i + 1], dpl[i], i); } for (int i = m + 1; i <= r; i++) { update(dpr[i - 1], dpr[i], i); } vector<int> qid_l, qid_r; for (auto i : qid) { auto [nl, nr, nc] = query[i]; if (nr <= m) { qid_l.push_back(i); } else if (nl > m) { qid_r.push_back(i); } else { for (int j = 0; j <= nc; j++) { ans[i] = max(ans[i], dpl[nl][j] + dpr[nr][nc - j]); } } } solve(solve, l, m, qid_l); solve(solve, m + 1, r, qid_r); }; vector<int> qid(q); iota(qid.begin(), qid.end(), 0); solve(solve, 1, n, qid); for (int i = 0; i < q; i++) { cout << ans[i] << "\n"; }
return 0; }
|