#include <bits/stdc++.h>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
long long n, m, k;
cin >> n >> m >> k;
vector<long long> descending;
vector<vector<long long>> ascending;
for (int i = 0; i < n; ++i)
{
vector<long long> a(m);
for (int i = 0; i < m; ++i) cin >> a[i];
bool b = false;
for (int i = 1; i < m; ++i)
{
if (a[i] > a[i - 1]) b = true;
}
if (b) ascending.push_back(a);
else
{
for (long long v : a) descending.push_back(v);
}
}
sort(descending.begin(), descending.end(), greater<long long>());
vector<long long> descendingAnswers(n * m + 2);
for (int i = 1; i <= (int) descending.size(); ++i)
{
descendingAnswers[i] = descendingAnswers[i - 1] + descending[i - 1];
}
vector<vector<pair<long long, int>>> prefLeft(m + 1);
vector<long long> prefCurrent(m + 1, -1e18);
vector<long long> ascendingAnswers(n * m + 1);
vector<pair<long long, int>> order;
vector<bool> used(n * m + 1);
for (int i = 0; i < (int) ascending.size(); ++i)
{
long long sum = 0;
for (int j = 0; j < m; ++j)
{
sum += ascending[i][j];
prefLeft[j + 1].emplace_back(sum, i);
}
order.emplace_back(sum, i);
}
for (int i = 0; i <= m; ++i) sort(prefLeft[i].begin(), prefLeft[i].end());
sort(order.begin(), order.end());
long long total = 0;
for (int i = 1; i <= k; ++i)
{
if (i % m == 0)
{
if (!order.empty())
{
total += order.back().first;
used[order.back().second] = true;
long long sum = 0;
for (int j = 0; j < m; ++j)
{
sum += ascending[order.back().second][j];
prefCurrent[j + 1] = max(prefCurrent[j + 1], sum - order.back().first);
}
order.pop_back();
}
ascendingAnswers[i] = total;
}
else
{
int left = i % m;
while (!prefLeft[left].empty() && used[prefLeft[left].back().second])
{
prefLeft[left].pop_back();
}
long long v1 = total;
if (!prefLeft[left].empty())
{
v1 += prefLeft[left].back().first;
}
long long v2 = total;
if (!order.empty())
{
v2 += order.back().first + prefCurrent[left];
}
ascendingAnswers[i] = max(v1, v2);
}
}
long long answer = 0;
for (int i = 0; i <= k; ++i)
{
answer = max(answer, descendingAnswers[i] + ascendingAnswers[k - i]);
}
cout << answer << '\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 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 | #include <bits/stdc++.h> using namespace std; int main() { ios_base::sync_with_stdio(false); cin.tie(0); long long n, m, k; cin >> n >> m >> k; vector<long long> descending; vector<vector<long long>> ascending; for (int i = 0; i < n; ++i) { vector<long long> a(m); for (int i = 0; i < m; ++i) cin >> a[i]; bool b = false; for (int i = 1; i < m; ++i) { if (a[i] > a[i - 1]) b = true; } if (b) ascending.push_back(a); else { for (long long v : a) descending.push_back(v); } } sort(descending.begin(), descending.end(), greater<long long>()); vector<long long> descendingAnswers(n * m + 2); for (int i = 1; i <= (int) descending.size(); ++i) { descendingAnswers[i] = descendingAnswers[i - 1] + descending[i - 1]; } vector<vector<pair<long long, int>>> prefLeft(m + 1); vector<long long> prefCurrent(m + 1, -1e18); vector<long long> ascendingAnswers(n * m + 1); vector<pair<long long, int>> order; vector<bool> used(n * m + 1); for (int i = 0; i < (int) ascending.size(); ++i) { long long sum = 0; for (int j = 0; j < m; ++j) { sum += ascending[i][j]; prefLeft[j + 1].emplace_back(sum, i); } order.emplace_back(sum, i); } for (int i = 0; i <= m; ++i) sort(prefLeft[i].begin(), prefLeft[i].end()); sort(order.begin(), order.end()); long long total = 0; for (int i = 1; i <= k; ++i) { if (i % m == 0) { if (!order.empty()) { total += order.back().first; used[order.back().second] = true; long long sum = 0; for (int j = 0; j < m; ++j) { sum += ascending[order.back().second][j]; prefCurrent[j + 1] = max(prefCurrent[j + 1], sum - order.back().first); } order.pop_back(); } ascendingAnswers[i] = total; } else { int left = i % m; while (!prefLeft[left].empty() && used[prefLeft[left].back().second]) { prefLeft[left].pop_back(); } long long v1 = total; if (!prefLeft[left].empty()) { v1 += prefLeft[left].back().first; } long long v2 = total; if (!order.empty()) { v2 += order.back().first + prefCurrent[left]; } ascendingAnswers[i] = max(v1, v2); } } long long answer = 0; for (int i = 0; i <= k; ++i) { answer = max(answer, descendingAnswers[i] + ascendingAnswers[k - i]); } cout << answer << '\n'; } |
English