#include "bits/stdc++.h" using namespace std; using ll = long long; struct Segment_Tree { int p, M; vector <long long> tree; Segment_Tree(int n) { p = 1; while (!((1 << p) - (1 << (p - 1)) >= n)) p++; M = (1 << (p - 1)); tree.resize(1 << p, 0); } Segment_Tree(vector <int> &v) { int n = (int)v.size(); p = 1; while (!((1 << p) - (1 << (p - 1)) >= n)) p++; M = (1 << (p - 1)); tree.resize(1 << p, 0); for (int i = 0; i < n; i++) tree[i + M] = v[i]; for (int i = M - 1; i >= 1; i--) tree[i] = max(tree[2 * i], tree[2 * i + 1]); } long long query(int a, int b) { a += M; b += M; long long ans = tree[a]; if (a != b) ans = max(ans, tree[b]); while (a / 2 != b / 2) { if (a % 2 == 0) ans = max(ans, tree[a + 1]); if (b % 2 == 1) ans = max(ans, tree[b - 1]); a /= 2; b /= 2; } return ans; } void update(int a, long long v) { a += M; tree[a] = v; a /= 2; while (a) { tree[a] = max(tree[2 * a], tree[2 * a + 1]); a /= 2; } } }; const int MAXW = 5e5; int main() { int n; ll c; cin >> n >> c; Segment_Tree dp(MAXW + 2); vector <vector <pair <ll, ll>>> v; for (int i = 0; i < n; i++) { ll a, w; cin >> a >> w; if (!v.empty() && v.back().back().first == a) v.back().push_back({a, w}); else v.push_back({{a, w}}); } for (auto &vec : v) { vector <pair <int, ll>> change; for (auto &[a, b] : vec) { ll cur0 = max(dp.query(0, b - 1), dp.query(b + 1, MAXW + 1)) + a - c; ll cur1 = dp.query(b, b) + a; change.push_back({b, max(cur0, cur1)}); } for (auto &[a, b] : change) { if (dp.query(a, a) < b) dp.update(a, b); } } cout << dp.query(1, MAXW) << '\n'; }
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 | #include "bits/stdc++.h" using namespace std; using ll = long long; struct Segment_Tree { int p, M; vector <long long> tree; Segment_Tree(int n) { p = 1; while (!((1 << p) - (1 << (p - 1)) >= n)) p++; M = (1 << (p - 1)); tree.resize(1 << p, 0); } Segment_Tree(vector <int> &v) { int n = (int)v.size(); p = 1; while (!((1 << p) - (1 << (p - 1)) >= n)) p++; M = (1 << (p - 1)); tree.resize(1 << p, 0); for (int i = 0; i < n; i++) tree[i + M] = v[i]; for (int i = M - 1; i >= 1; i--) tree[i] = max(tree[2 * i], tree[2 * i + 1]); } long long query(int a, int b) { a += M; b += M; long long ans = tree[a]; if (a != b) ans = max(ans, tree[b]); while (a / 2 != b / 2) { if (a % 2 == 0) ans = max(ans, tree[a + 1]); if (b % 2 == 1) ans = max(ans, tree[b - 1]); a /= 2; b /= 2; } return ans; } void update(int a, long long v) { a += M; tree[a] = v; a /= 2; while (a) { tree[a] = max(tree[2 * a], tree[2 * a + 1]); a /= 2; } } }; const int MAXW = 5e5; int main() { int n; ll c; cin >> n >> c; Segment_Tree dp(MAXW + 2); vector <vector <pair <ll, ll>>> v; for (int i = 0; i < n; i++) { ll a, w; cin >> a >> w; if (!v.empty() && v.back().back().first == a) v.back().push_back({a, w}); else v.push_back({{a, w}}); } for (auto &vec : v) { vector <pair <int, ll>> change; for (auto &[a, b] : vec) { ll cur0 = max(dp.query(0, b - 1), dp.query(b + 1, MAXW + 1)) + a - c; ll cur1 = dp.query(b, b) + a; change.push_back({b, max(cur0, cur1)}); } for (auto &[a, b] : change) { if (dp.query(a, a) < b) dp.update(a, b); } } cout << dp.query(1, MAXW) << '\n'; } |