| # | Time | Username | Problem | Language | Result | Execution time | Memory |
|---|---|---|---|---|---|---|---|
| 1343370 | maxied | Bikeparking (EGOI24_bikeparking) | C++20 | 0 ms | 0 KiB |
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> x(n), y(n);
for (int i = 0; i < n; i++){
cin >> x[i];
}
for (int i = 0; i < n; i++){
cin >> y[i];
}
if (n <= 100 && *max_element(x.begin(), x.end()) <= 100 && *max_element(y.begin(), y.end()) <= 100){
int sum = 0;
for (int i = 0; i < n; i++){
sum += y[i];
}
int ans = -INT_MAX;
for (int bully = 0; bully <= sum; bully++){
int cur = 0;
// assign the bullied to the worst position
// assign the rest to the best position
int cbully = bully;
int rest = sum - bully;
vector<int> tx = x;
vector<int> ty = y;
int l = 0;
int r = n - 1;
int tkn = 0;
int i = 0;
// these people have tier i
// l/r is the thing they are given
// tx is the free spots
// ty is the people taking
while (i < n){
if (!cbully){
if (!rest){
break;
}
int take = min(tx[l], min(rest, ty[i]));
//cout << i << "take rest " << take << '\n';
if (i < l){
cur -= take;
}
else if (i > l){
cur += take;
}
tx[l] -= take;
rest -= take;
ty[i] -= take;
if (tx[l] == 0){
l++;
}
if (ty[i] == 0){
i++;
}
continue;
}
int take = min(tx[r], min(cbully, ty[i]));
//cout << i << "take bully " << take << '\n';
if (i < r){
cur -= take;
}
else if (i > r){
cur += take;
}
tx[r] -= take;
cbully -= take;
ty[i] -= take;
if (tx[r] == 0){
r--;
}
if (ty[i] == 0){
i++;
}
}
//cout << bully << ' ' << cur << endl;
ans = max(ans, cur);
}
cout << ans << '\n';
}
return 0;
}
int sum = 0;
for (int i = 0; i < n; i++){
sum += y[i];
}
int ans = -INT_MAX;
// it will decrease, then increase.
auto f = [&](int bully) -> int{
int cur = 0;
// assign the bullied to the worst position
// assign the rest to the best position
int cbully = bully;
int rest = sum - bully;
vector<int> tx = x;
vector<int> ty = y;
int l = 0;
int r = n - 1;
int tkn = 0;
int i = 0;
// these people have tier i
// l/r is the thing they are given
// tx is the free spots
// ty is the people taking
while (i < n){
if (!cbully){
if (!rest){
break;
}
int take = min(tx[l], min(rest, ty[i]));
//cout << i << "take rest " << take << '\n';
if (i < l){
cur -= take;
}
else if (i > l){
cur += take;
}
tx[l] -= take;
rest -= take;
ty[i] -= take;
if (tx[l] == 0){
l++;
}
if (ty[i] == 0){
i++;
}
continue;
}
int take = min(tx[r], min(cbully, ty[i]));
//cout << i << "take bully " << take << '\n';
if (i < r){
cur -= take;
}
else if (i > r){
cur += take;
}
tx[r] -= take;
cbully -= take;
ty[i] -= take;
if (tx[r] == 0){
r--;
}
if (ty[i] == 0){
i++;
}
}
return cur;
};
int lowest = f(sum);
int lo = 0, hi = sum - 1;
// first point where its not lowest
// TTTFFF
while (lo < hi){
int mid = (lo + hi + 1) >> 1;
if (f(mid) == lowest){
hi = mid - 1;
}
else{
lo = mid;
}
}
hi = lo;
lo = 0;
// find first point where f(x) > f(x + 1)
// FFFFFFTTTTT
while (lo < hi){
int mid = (lo + hi) >> 1;
if (f(mid) >= f(mid + 1)){
hi = mid;
}
else{
lo = mid + 1;
}
}
cout << f(lo) << '\n';
}
