#include<cstdio>
#include<vector>
using namespace std;
constexpr auto N = 500005;
long long DP[N];
long long A[N];
long long W[N];
long long MAX[N];
struct para {
long long dp;
long long w;
para(long long dp1, long long w1) : dp(dp1), w(w1) {}
};
para max1 = para(-1, -1);
para max2 = para(-1, -1);
static void dodajMax(long long dp, long long w) {
MAX[w] = dp;
if (dp > max1.dp) {
max2 = max1;
max1 = para(dp, w);
}
else if (dp > max2.dp) {
max2 = para(dp, w);
}
}
long long max(long long a, long long b) {
return a > b ? a : b;
}
long long maxInny(long long w) {
if (max1.w != -1 && max1.w != w) {
return max1.dp;
}
if (max2.w != -1 && max2.w != w) {
return max2.dp;
}
return 0;
}
int main() {
long long n, c;
scanf("%lld %lld", &n, &c);
vector<para> maksima;
for (int i = 0; i < n; i++) {
scanf("%lld %lld", &A[i], &W[i]);
}
// Najlepszy wynik do i z użyciem i;
DP[0] = A[0];
maksima.push_back(para(DP[0], W[0]));
for (int i = 1; i < n; i++) {
if (A[i] != A[i - 1]) {
// skonsumuj maksima
for (auto it = maksima.begin(); it != maksima.end(); it++) {
dodajMax(it->dp, it->w);
}
maksima.clear();
}
DP[i] = A[i];
long long r1 = MAX[W[i]] + A[i];
long long r2 = maxInny(W[i]) + A[i] - c;
DP[i] = max(DP[i], r1);
DP[i] = max(DP[i], r2);
maksima.push_back(para(DP[i], W[i]));
}
long long result = DP[0];
for (int i = 0; i < n; i++) {
result = max(result, DP[i]);
}
printf("%lld", result);
return 0;
}
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 87 88 | #include<cstdio> #include<vector> using namespace std; constexpr auto N = 500005; long long DP[N]; long long A[N]; long long W[N]; long long MAX[N]; struct para { long long dp; long long w; para(long long dp1, long long w1) : dp(dp1), w(w1) {} }; para max1 = para(-1, -1); para max2 = para(-1, -1); static void dodajMax(long long dp, long long w) { MAX[w] = dp; if (dp > max1.dp) { max2 = max1; max1 = para(dp, w); } else if (dp > max2.dp) { max2 = para(dp, w); } } long long max(long long a, long long b) { return a > b ? a : b; } long long maxInny(long long w) { if (max1.w != -1 && max1.w != w) { return max1.dp; } if (max2.w != -1 && max2.w != w) { return max2.dp; } return 0; } int main() { long long n, c; scanf("%lld %lld", &n, &c); vector<para> maksima; for (int i = 0; i < n; i++) { scanf("%lld %lld", &A[i], &W[i]); } // Najlepszy wynik do i z użyciem i; DP[0] = A[0]; maksima.push_back(para(DP[0], W[0])); for (int i = 1; i < n; i++) { if (A[i] != A[i - 1]) { // skonsumuj maksima for (auto it = maksima.begin(); it != maksima.end(); it++) { dodajMax(it->dp, it->w); } maksima.clear(); } DP[i] = A[i]; long long r1 = MAX[W[i]] + A[i]; long long r2 = maxInny(W[i]) + A[i] - c; DP[i] = max(DP[i], r1); DP[i] = max(DP[i], r2); maksima.push_back(para(DP[i], W[i])); } long long result = DP[0]; for (int i = 0; i < n; i++) { result = max(result, DP[i]); } printf("%lld", result); return 0; } |
English