#include <bits/stdc++.h>
using namespace std;
int main() {
cin.tie(nullptr);
ios_base::sync_with_stdio(false);
int n, m, k; cin >> n >> m >> k;
vector<long long> decreasingGigaStack;
vector<vector<long long>> increasingStacks;
vector<long long> inp(m); bool isIncreasing = false;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
cin >> inp[j];
if(j > 0 && inp[j] > inp[j-1]) isIncreasing = true;
}
if(isIncreasing) increasingStacks.push_back(inp);
else {
for(int p = 0; p < m; p++) {
decreasingGigaStack.push_back(inp[p]);
}
}
isIncreasing = false;
}
sort(decreasingGigaStack.begin(), decreasingGigaStack.end(), greater<long long>());
vector<set<pair<long long, int>>> bestPrefSum(m);
vector<pair<long long, int>> sums(increasingStacks.size());
vector<long long> matchedSums(increasingStacks.size());
long long prefSum;
for(int i = 0; i < increasingStacks.size(); i++) {
prefSum = 0;
for(int j = 0; j < m; j++) {
prefSum += increasingStacks[i][j];
bestPrefSum[j].insert({-prefSum, i});
}
sums[i] = {prefSum, i};
matchedSums[i] = prefSum;
}
sort(sums.begin(), sums.end(), greater<pair<long long, int>>());
int kFull = k;
k = increasingStacks.size() * m;
int bestin, bestin2;
long long bestinval, bestinval2;
long long wholeTotal = 0;
set<int> bestIds;
vector<long long> bestResultsIncreasing(k+1, 0);
for(int i = 1; i <= k; i++) {
if(i % m == 0) {
bestIds.insert(sums[i/m-1].second);
wholeTotal += sums[i/m-1].first;
bestResultsIncreasing[i] = wholeTotal;
continue;
}
bestin = -1; bestin2 = -1;
auto it = bestPrefSum[i%m-1].begin();
while(true) {
if(bestIds.count((*it).second) != 0) {
if(bestin == -1) { bestin = (*it).second; bestinval = -(*it).first; }
else { bestin2 = (*it).second; bestinval2 = -(*it).first; }
} else {
if(bestin != -1 && bestin2 != -1) {
if(bestinval - matchedSums[bestin] > bestinval2 - matchedSums[bestin2]) {
// bestin jest lepszy w reszcie (i%m)
bestPrefSum[i%m-1].erase({-bestinval2, bestin2});
} else {
bestPrefSum[i%m-1].erase({-bestinval, bestin});
bestinval = bestinval2; bestin = bestin2;
}
}
if(bestin != -1) {
// Porownanie najlepszego in z najlepszym out.
if(bestinval + sums[i/m].first > -(*it).first + matchedSums[bestin]) {
bestResultsIncreasing[i] = wholeTotal-matchedSums[bestin]+bestinval+sums[i/m].first;
break;
}
}
bestResultsIncreasing[i] = wholeTotal-(*it).first;
break;
}
++it;
}
}
vector<long long> bestResultsDecreasing(decreasingGigaStack.size()+1, 0);
long long decsum = 0;
for(int i = 0; i < decreasingGigaStack.size(); i++) {
decsum += decreasingGigaStack[i];
bestResultsDecreasing[i+1] = decsum;
}
long long result = 0;
int j = kFull;
if(j > bestResultsIncreasing.size()-1) {
j = bestResultsIncreasing.size()-1;
}
int i = kFull - j;
while(i < bestResultsDecreasing.size() && j >= 0) {
if(bestResultsIncreasing[j] + bestResultsDecreasing[i] > result) {
result = bestResultsIncreasing[j] + bestResultsDecreasing[i];
}
i++; j--;
}
cout << result << '\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 | #include <bits/stdc++.h> using namespace std; int main() { cin.tie(nullptr); ios_base::sync_with_stdio(false); int n, m, k; cin >> n >> m >> k; vector<long long> decreasingGigaStack; vector<vector<long long>> increasingStacks; vector<long long> inp(m); bool isIncreasing = false; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { cin >> inp[j]; if(j > 0 && inp[j] > inp[j-1]) isIncreasing = true; } if(isIncreasing) increasingStacks.push_back(inp); else { for(int p = 0; p < m; p++) { decreasingGigaStack.push_back(inp[p]); } } isIncreasing = false; } sort(decreasingGigaStack.begin(), decreasingGigaStack.end(), greater<long long>()); vector<set<pair<long long, int>>> bestPrefSum(m); vector<pair<long long, int>> sums(increasingStacks.size()); vector<long long> matchedSums(increasingStacks.size()); long long prefSum; for(int i = 0; i < increasingStacks.size(); i++) { prefSum = 0; for(int j = 0; j < m; j++) { prefSum += increasingStacks[i][j]; bestPrefSum[j].insert({-prefSum, i}); } sums[i] = {prefSum, i}; matchedSums[i] = prefSum; } sort(sums.begin(), sums.end(), greater<pair<long long, int>>()); int kFull = k; k = increasingStacks.size() * m; int bestin, bestin2; long long bestinval, bestinval2; long long wholeTotal = 0; set<int> bestIds; vector<long long> bestResultsIncreasing(k+1, 0); for(int i = 1; i <= k; i++) { if(i % m == 0) { bestIds.insert(sums[i/m-1].second); wholeTotal += sums[i/m-1].first; bestResultsIncreasing[i] = wholeTotal; continue; } bestin = -1; bestin2 = -1; auto it = bestPrefSum[i%m-1].begin(); while(true) { if(bestIds.count((*it).second) != 0) { if(bestin == -1) { bestin = (*it).second; bestinval = -(*it).first; } else { bestin2 = (*it).second; bestinval2 = -(*it).first; } } else { if(bestin != -1 && bestin2 != -1) { if(bestinval - matchedSums[bestin] > bestinval2 - matchedSums[bestin2]) { // bestin jest lepszy w reszcie (i%m) bestPrefSum[i%m-1].erase({-bestinval2, bestin2}); } else { bestPrefSum[i%m-1].erase({-bestinval, bestin}); bestinval = bestinval2; bestin = bestin2; } } if(bestin != -1) { // Porownanie najlepszego in z najlepszym out. if(bestinval + sums[i/m].first > -(*it).first + matchedSums[bestin]) { bestResultsIncreasing[i] = wholeTotal-matchedSums[bestin]+bestinval+sums[i/m].first; break; } } bestResultsIncreasing[i] = wholeTotal-(*it).first; break; } ++it; } } vector<long long> bestResultsDecreasing(decreasingGigaStack.size()+1, 0); long long decsum = 0; for(int i = 0; i < decreasingGigaStack.size(); i++) { decsum += decreasingGigaStack[i]; bestResultsDecreasing[i+1] = decsum; } long long result = 0; int j = kFull; if(j > bestResultsIncreasing.size()-1) { j = bestResultsIncreasing.size()-1; } int i = kFull - j; while(i < bestResultsDecreasing.size() && j >= 0) { if(bestResultsIncreasing[j] + bestResultsDecreasing[i] > result) { result = bestResultsIncreasing[j] + bestResultsDecreasing[i]; } i++; j--; } cout << result << '\n'; } |
English