#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int stacks_num, stack_size, max_eat;
vector<pair<ll, int>> stackSum;
vector<vector<ll>> stacks;
vector<ll> stos;
deque<ll> pancakes;
ll val(int i, ll sum, ll x)
{
if (x >= i)
{
if (x * stack_size > max_eat)
return 0;
return stackSum[x].first - sum + pancakes[min(max_eat - stack_size * x, (ll)pancakes.size() - 1)];
}
if ((x + 1) * stack_size > max_eat)
return 0;
return stackSum[x].first + pancakes[min(max_eat - stack_size * (x + 1), (ll)pancakes.size() - 1)];
}
int binsearchlower(int i, ll sum, int l, int r)
{
if (l == r)
{
return l;
}
int mid = (l + r) / 2;
ll val1 = val(i, sum, mid);
ll val2 = val(i, sum, mid + 1);
if (val1 >= val2)
{
return binsearchlower(i, sum, l, mid);
}
else
{
return binsearchlower(i, sum, mid + 1, r);
}
}
int binsearchupper(int i, ll sum, int l, int r)
{
if (l == r)
{
return l;
}
int mid = (l + r) / 2;
ll val1 = val(i, sum, mid);
ll val2 = val(i, sum, mid + 1);
if (val1 > val2)
{
return binsearchupper(i, sum, l, mid);
}
else
{
return binsearchupper(i, sum, mid + 1, r);
}
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> stacks_num >> stack_size >> max_eat;
stacks.resize(stacks_num);
stos.resize(stack_size);
for (int i = 0; i < stacks_num; i++)
{
bool asc = 0;
for (int j = 0; j < stack_size; j++)
{
cin >> stos[j];
if (j > 0 && stos[j - 1] < stos[j])
{
asc = true;
}
}
if (asc == 0)
{
for (int j = 0; j < stack_size; j++)
{
pancakes.push_back(stos[j]);
}
}
else
{
ll sum = 0;
for (int j = 0; j < stack_size; j++)
{
sum += stos[j];
stacks[i].push_back(sum);
}
stackSum.push_back({sum, i});
}
}
sort(stackSum.begin(), stackSum.end(), greater<pair<ll, int>>());
sort(pancakes.begin(), pancakes.end(), greater<ll>());
pancakes.push_front(0);
ll wyn = 0;
for (int i = 1; i < pancakes.size(); i++)
{
pancakes[i] += pancakes[i - 1];
}
for (int i = 1; i < stackSum.size(); i++)
{
stackSum[i].first += stackSum[i - 1].first;
}
wyn = max(wyn, pancakes[min((int)pancakes.size() - 1, max_eat)]);
for (int i = 0; i < stackSum.size(); i++)
{
auto &id = stackSum[i].second;
for (int j = 0; j < stacks[id].size(); j++)
{
// cout << stacks[id][j] << "\n";
if (j + 1 > max_eat)
{
break;
}
max_eat -= j + 1;
wyn = max(wyn, stacks[id][j] + pancakes[min((int)pancakes.size() - 1, max_eat)]);
auto x = binsearchlower(i, stacks[id].back(), 0, stackSum.size() - 1);
// cout << "x:" << x << "\n";
if (x >= i)
{
if (max_eat - stack_size * x >= 0)
{
// cout << "wyn" << stacks[id][j] + stackSum[x].first - stacks[id].back() + pancakes[min(max_eat - stack_size * x, (int)pancakes.size() - 1)] << "\n";
wyn = max(wyn, stacks[id][j] + stackSum[x].first - stacks[id].back() + pancakes[min(max_eat - stack_size * x, (int)pancakes.size() - 1)]);
}
}
else
{
if (max_eat - stack_size * (x + 1) >= 0)
{
wyn = max(wyn, stacks[id][j] + stackSum[x].first + pancakes[min(max_eat - stack_size * (x + 1), (int)pancakes.size() - 1)]);
// cout << "wyn" << stacks[id][j] + stackSum[x].first + pancakes[min(max_eat - stack_size * (x + 1), (int)pancakes.size() - 1)] << "\n";
}
}
x = binsearchupper(i, stacks[id].back(), 0, stackSum.size() - 1);
if (x >= i)
{
if (max_eat - stack_size * x >= 0)
{
// cout << "wyn" << stacks[id][j] + stackSum[x].first - stacks[id].back() + pancakes[min(max_eat - stack_size * x, (int)pancakes.size() - 1)] << "\n";
wyn = max(wyn, stacks[id][j] + stackSum[x].first - stacks[id].back() + pancakes[min(max_eat - stack_size * x, (int)pancakes.size() - 1)]);
}
}
else
{
if (max_eat - stack_size * (x + 1) >= 0)
{
wyn = max(wyn, stacks[id][j] + stackSum[x].first + pancakes[min(max_eat - stack_size * (x + 1), (int)pancakes.size() - 1)]);
// cout << "wyn" << stacks[id][j] + stackSum[x].first + pancakes[min(max_eat - stack_size * (x + 1), (int)pancakes.size() - 1)] << "\n";
}
}
max_eat += j + 1;
}
}
// auto x = binsearch(stackSum.size() + 1000, 0, 0, stackSum.size() - 1);
// // x = 1;
// // cout << x << " " << max_eat << " " << stackSum[x].first << "\n";
// if (max_eat - stack_size * (x + 1) >= 0)
// {
// wyn = max(wyn, stackSum[x].first + pancakes[min(max_eat - stack_size * (x + 1), (int)pancakes.size() - 1)]);
// }
cout << wyn << "\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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | #include <bits/stdc++.h> using namespace std; using ll = long long; int stacks_num, stack_size, max_eat; vector<pair<ll, int>> stackSum; vector<vector<ll>> stacks; vector<ll> stos; deque<ll> pancakes; ll val(int i, ll sum, ll x) { if (x >= i) { if (x * stack_size > max_eat) return 0; return stackSum[x].first - sum + pancakes[min(max_eat - stack_size * x, (ll)pancakes.size() - 1)]; } if ((x + 1) * stack_size > max_eat) return 0; return stackSum[x].first + pancakes[min(max_eat - stack_size * (x + 1), (ll)pancakes.size() - 1)]; } int binsearchlower(int i, ll sum, int l, int r) { if (l == r) { return l; } int mid = (l + r) / 2; ll val1 = val(i, sum, mid); ll val2 = val(i, sum, mid + 1); if (val1 >= val2) { return binsearchlower(i, sum, l, mid); } else { return binsearchlower(i, sum, mid + 1, r); } } int binsearchupper(int i, ll sum, int l, int r) { if (l == r) { return l; } int mid = (l + r) / 2; ll val1 = val(i, sum, mid); ll val2 = val(i, sum, mid + 1); if (val1 > val2) { return binsearchupper(i, sum, l, mid); } else { return binsearchupper(i, sum, mid + 1, r); } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> stacks_num >> stack_size >> max_eat; stacks.resize(stacks_num); stos.resize(stack_size); for (int i = 0; i < stacks_num; i++) { bool asc = 0; for (int j = 0; j < stack_size; j++) { cin >> stos[j]; if (j > 0 && stos[j - 1] < stos[j]) { asc = true; } } if (asc == 0) { for (int j = 0; j < stack_size; j++) { pancakes.push_back(stos[j]); } } else { ll sum = 0; for (int j = 0; j < stack_size; j++) { sum += stos[j]; stacks[i].push_back(sum); } stackSum.push_back({sum, i}); } } sort(stackSum.begin(), stackSum.end(), greater<pair<ll, int>>()); sort(pancakes.begin(), pancakes.end(), greater<ll>()); pancakes.push_front(0); ll wyn = 0; for (int i = 1; i < pancakes.size(); i++) { pancakes[i] += pancakes[i - 1]; } for (int i = 1; i < stackSum.size(); i++) { stackSum[i].first += stackSum[i - 1].first; } wyn = max(wyn, pancakes[min((int)pancakes.size() - 1, max_eat)]); for (int i = 0; i < stackSum.size(); i++) { auto &id = stackSum[i].second; for (int j = 0; j < stacks[id].size(); j++) { // cout << stacks[id][j] << "\n"; if (j + 1 > max_eat) { break; } max_eat -= j + 1; wyn = max(wyn, stacks[id][j] + pancakes[min((int)pancakes.size() - 1, max_eat)]); auto x = binsearchlower(i, stacks[id].back(), 0, stackSum.size() - 1); // cout << "x:" << x << "\n"; if (x >= i) { if (max_eat - stack_size * x >= 0) { // cout << "wyn" << stacks[id][j] + stackSum[x].first - stacks[id].back() + pancakes[min(max_eat - stack_size * x, (int)pancakes.size() - 1)] << "\n"; wyn = max(wyn, stacks[id][j] + stackSum[x].first - stacks[id].back() + pancakes[min(max_eat - stack_size * x, (int)pancakes.size() - 1)]); } } else { if (max_eat - stack_size * (x + 1) >= 0) { wyn = max(wyn, stacks[id][j] + stackSum[x].first + pancakes[min(max_eat - stack_size * (x + 1), (int)pancakes.size() - 1)]); // cout << "wyn" << stacks[id][j] + stackSum[x].first + pancakes[min(max_eat - stack_size * (x + 1), (int)pancakes.size() - 1)] << "\n"; } } x = binsearchupper(i, stacks[id].back(), 0, stackSum.size() - 1); if (x >= i) { if (max_eat - stack_size * x >= 0) { // cout << "wyn" << stacks[id][j] + stackSum[x].first - stacks[id].back() + pancakes[min(max_eat - stack_size * x, (int)pancakes.size() - 1)] << "\n"; wyn = max(wyn, stacks[id][j] + stackSum[x].first - stacks[id].back() + pancakes[min(max_eat - stack_size * x, (int)pancakes.size() - 1)]); } } else { if (max_eat - stack_size * (x + 1) >= 0) { wyn = max(wyn, stacks[id][j] + stackSum[x].first + pancakes[min(max_eat - stack_size * (x + 1), (int)pancakes.size() - 1)]); // cout << "wyn" << stacks[id][j] + stackSum[x].first + pancakes[min(max_eat - stack_size * (x + 1), (int)pancakes.size() - 1)] << "\n"; } } max_eat += j + 1; } } // auto x = binsearch(stackSum.size() + 1000, 0, 0, stackSum.size() - 1); // // x = 1; // // cout << x << " " << max_eat << " " << stackSum[x].first << "\n"; // if (max_eat - stack_size * (x + 1) >= 0) // { // wyn = max(wyn, stackSum[x].first + pancakes[min(max_eat - stack_size * (x + 1), (int)pancakes.size() - 1)]); // } cout << wyn << "\n"; } |
English