#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>
typedef long long ll;
const ll INF = LLONG_MAX;
struct stack {
std::vector<ll> val, top, bottom;
ll sum;
};
struct solve {
int n_inc, n_dec, m, k;
std::vector<ll> decreasing;
std::vector<stack> increasing;
std::vector<ll> sum_pref, dec_pref;
std::vector<std::vector<ll>> max_top_suf, min_bottom_pref;
solve() {
input();
preprocess();
ll ans = 0;
int beg = std::max(0, k - n_inc * m);
int end = std::min(k, n_dec * m);
for (int k_dec = beg; k_dec <= end; k_dec++) {
int k_inc = k - k_dec;
int whole = k_inc / m;
int rest = k_inc % m;
//std::cerr << "k_dec: " << k_dec << " k_inc: " << k_inc << " whole: " << whole << " rest: " << rest << "\n";
ll inc_total = sum_pref[whole];
if (rest > 0) {
inc_total += max_top_suf[whole+1][rest];
ll inc_total2 = sum_pref[whole+1] - min_bottom_pref[whole+1][m - rest];
//std::cerr << "inc_total: " << inc_total << ' ' << inc_total2 << "\n";
inc_total = std::max(inc_total, inc_total2);
}
ans = std::max(ans, inc_total + dec_pref[k_dec]);
}
std::cout << ans << '\n';
}
void preprocess() {
std::sort(decreasing.begin(), decreasing.end(), std::greater<>());
std::sort(increasing.begin(), increasing.end(), [&](auto& a, auto& b) { return a.sum > b.sum; });
decreasing[0] = 0;
increasing[0].sum = 0;
//std::cerr << "decreasing:"; for (auto x : decreasing) std::cerr << ' ' << x; std::cerr << '\n';
//std::cerr << "increasing:\n";
//for (int i = 0; i < increasing.size(); i++) {
// std::cerr << i << ":\n";
// std::cerr << "val: "; for (auto x : increasing[i].val) std::cerr << ' ' << x; std::cerr << '\n';
// std::cerr << "top: "; for (auto x : increasing[i].top) std::cerr << ' ' << x; std::cerr << '\n';
// std::cerr << "bottom:"; for (auto x : increasing[i].bottom) std::cerr << ' ' << x; std::cerr << '\n';
// std::cerr << "sum: " << increasing[i].sum << '\n';
//}
for (int i = 1; i < dec_pref.size(); i++) dec_pref[i] = dec_pref[i-1] + decreasing[i];
//std::cerr << "dec_pref:"; for (auto x : dec_pref) std::cerr << ' ' << x; std::cerr << '\n';
if (n_inc == 0) return;
for (int i = 1; i <= n_inc; i++) sum_pref[i] = sum_pref[i-1] + increasing[i].sum;
//std::cerr << "sum_pref:"; for (auto x : sum_pref) std::cerr << ' ' << x; std::cerr << '\n';
for (int j = 0; j <= m; j++) min_bottom_pref[1][j] = increasing[1].bottom[j];
for (int i = 2; i <= n_inc; i++) for (int j = 0; j <= m; j++)
min_bottom_pref[i][j] = std::min(min_bottom_pref[i-1][j], increasing[i].bottom[j]);
//std::cerr << "min_bottom_pref:\n";
//for (int i = 0; i < min_bottom_pref.size(); i++) {
// for (auto x : min_bottom_pref[i]) std::cerr << x << ' '; std::cerr << '\n';
//}
for (int j = 0; j <= m; j++) max_top_suf[n_inc][j] = increasing[n_inc].top[j];
for (int i = n_inc-1; i >= 0; i--) for (int j = 0; j <= m; j++)
max_top_suf[i][j] = std::max(max_top_suf[i+1][j], increasing[i].top[j]);
//std::cerr << "max_top_suf:\n";
//for (int i = 0; i < max_top_suf.size(); i++) {
// for (auto x : max_top_suf[i]) std::cerr << x << ' '; std::cerr << '\n';
// }
}
void input() {
int n; std::cin >> n >> m >> k;
decreasing.push_back(INF);
increasing.push_back({std::vector<ll>(m+1), std::vector<ll>(m+1), std::vector<ll>(m+1), INF});
std::vector<ll> a(m+1);
for (int i = 0; i < n; i++) {
for (int i = 1; i <= m; i++) std::cin >> a[i];
bool inc = false;
for (int i = 2; i <= m; i++) if (a[i] > a[i-1]) {
inc = true;
break;
}
if (inc) {
increasing.push_back({std::vector<ll>(m+1), std::vector<ll>(m+1), std::vector<ll>(m+1), 0});
auto& s = increasing.back();
for (int i = 1; i <= m; i++) {
s.val[i] = a[i];
s.sum += a[i];
s.top[i] = s.top[i-1] + a[i];
}
for (int i = 1; i <= m; i++) s.bottom[i] = s.bottom[i-1] + s.val[m+1-i];
}
else {
for (auto elem : a) decreasing.push_back(elem);
}
}
n_inc = increasing.size()-1;
n_dec = n - n_inc;
dec_pref = std::vector<ll>(decreasing.size());
sum_pref = std::vector<ll>(n_inc+1);
max_top_suf = std::vector<std::vector<ll>>(n_inc+1, std::vector<ll>(m+1));
min_bottom_pref = std::vector<std::vector<ll>>(n_inc+1, std::vector<ll>(m+1));
}
};
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
solve();
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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | #include <algorithm> #include <climits> #include <iostream> #include <vector> typedef long long ll; const ll INF = LLONG_MAX; struct stack { std::vector<ll> val, top, bottom; ll sum; }; struct solve { int n_inc, n_dec, m, k; std::vector<ll> decreasing; std::vector<stack> increasing; std::vector<ll> sum_pref, dec_pref; std::vector<std::vector<ll>> max_top_suf, min_bottom_pref; solve() { input(); preprocess(); ll ans = 0; int beg = std::max(0, k - n_inc * m); int end = std::min(k, n_dec * m); for (int k_dec = beg; k_dec <= end; k_dec++) { int k_inc = k - k_dec; int whole = k_inc / m; int rest = k_inc % m; //std::cerr << "k_dec: " << k_dec << " k_inc: " << k_inc << " whole: " << whole << " rest: " << rest << "\n"; ll inc_total = sum_pref[whole]; if (rest > 0) { inc_total += max_top_suf[whole+1][rest]; ll inc_total2 = sum_pref[whole+1] - min_bottom_pref[whole+1][m - rest]; //std::cerr << "inc_total: " << inc_total << ' ' << inc_total2 << "\n"; inc_total = std::max(inc_total, inc_total2); } ans = std::max(ans, inc_total + dec_pref[k_dec]); } std::cout << ans << '\n'; } void preprocess() { std::sort(decreasing.begin(), decreasing.end(), std::greater<>()); std::sort(increasing.begin(), increasing.end(), [&](auto& a, auto& b) { return a.sum > b.sum; }); decreasing[0] = 0; increasing[0].sum = 0; //std::cerr << "decreasing:"; for (auto x : decreasing) std::cerr << ' ' << x; std::cerr << '\n'; //std::cerr << "increasing:\n"; //for (int i = 0; i < increasing.size(); i++) { // std::cerr << i << ":\n"; // std::cerr << "val: "; for (auto x : increasing[i].val) std::cerr << ' ' << x; std::cerr << '\n'; // std::cerr << "top: "; for (auto x : increasing[i].top) std::cerr << ' ' << x; std::cerr << '\n'; // std::cerr << "bottom:"; for (auto x : increasing[i].bottom) std::cerr << ' ' << x; std::cerr << '\n'; // std::cerr << "sum: " << increasing[i].sum << '\n'; //} for (int i = 1; i < dec_pref.size(); i++) dec_pref[i] = dec_pref[i-1] + decreasing[i]; //std::cerr << "dec_pref:"; for (auto x : dec_pref) std::cerr << ' ' << x; std::cerr << '\n'; if (n_inc == 0) return; for (int i = 1; i <= n_inc; i++) sum_pref[i] = sum_pref[i-1] + increasing[i].sum; //std::cerr << "sum_pref:"; for (auto x : sum_pref) std::cerr << ' ' << x; std::cerr << '\n'; for (int j = 0; j <= m; j++) min_bottom_pref[1][j] = increasing[1].bottom[j]; for (int i = 2; i <= n_inc; i++) for (int j = 0; j <= m; j++) min_bottom_pref[i][j] = std::min(min_bottom_pref[i-1][j], increasing[i].bottom[j]); //std::cerr << "min_bottom_pref:\n"; //for (int i = 0; i < min_bottom_pref.size(); i++) { // for (auto x : min_bottom_pref[i]) std::cerr << x << ' '; std::cerr << '\n'; //} for (int j = 0; j <= m; j++) max_top_suf[n_inc][j] = increasing[n_inc].top[j]; for (int i = n_inc-1; i >= 0; i--) for (int j = 0; j <= m; j++) max_top_suf[i][j] = std::max(max_top_suf[i+1][j], increasing[i].top[j]); //std::cerr << "max_top_suf:\n"; //for (int i = 0; i < max_top_suf.size(); i++) { // for (auto x : max_top_suf[i]) std::cerr << x << ' '; std::cerr << '\n'; // } } void input() { int n; std::cin >> n >> m >> k; decreasing.push_back(INF); increasing.push_back({std::vector<ll>(m+1), std::vector<ll>(m+1), std::vector<ll>(m+1), INF}); std::vector<ll> a(m+1); for (int i = 0; i < n; i++) { for (int i = 1; i <= m; i++) std::cin >> a[i]; bool inc = false; for (int i = 2; i <= m; i++) if (a[i] > a[i-1]) { inc = true; break; } if (inc) { increasing.push_back({std::vector<ll>(m+1), std::vector<ll>(m+1), std::vector<ll>(m+1), 0}); auto& s = increasing.back(); for (int i = 1; i <= m; i++) { s.val[i] = a[i]; s.sum += a[i]; s.top[i] = s.top[i-1] + a[i]; } for (int i = 1; i <= m; i++) s.bottom[i] = s.bottom[i-1] + s.val[m+1-i]; } else { for (auto elem : a) decreasing.push_back(elem); } } n_inc = increasing.size()-1; n_dec = n - n_inc; dec_pref = std::vector<ll>(decreasing.size()); sum_pref = std::vector<ll>(n_inc+1); max_top_suf = std::vector<std::vector<ll>>(n_inc+1, std::vector<ll>(m+1)); min_bottom_pref = std::vector<std::vector<ll>>(n_inc+1, std::vector<ll>(m+1)); } }; int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); std::cout.tie(nullptr); solve(); return 0; } |
English