Submission #1343372

#TimeUsernameProblemLanguageResultExecution timeMemory
1343372maxiedBikeparking (EGOI24_bikeparking)C++20
68 / 100
272 ms5180 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';
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...