Submission #1204832

#TimeUsernameProblemLanguageResultExecution timeMemory
1204832aquasocuteSnowball (JOI21_ho_t2)C++20
0 / 100
1 ms328 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 2000005;      // ← bump this up by a few
ll n, q, a[MAXN], ans[MAXN];

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> q;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }

    // 1) Build the prefix‐sum‐of‐nonzeros array
    vector<ll> megu;
    megu.reserve(q);
    while(q--){
        ll x; 
        cin >> x;
        if(x == 0) continue;
        if(megu.empty()) megu.push_back(x);
        else            megu.push_back(megu.back() + x);
    }

    // 2) Extract only the “record” maxima (positive) and minima (negative)
    vector<ll> aquaa;
    aquaa.reserve(megu.size());
    ll bestPos = 0, bestNeg = 0;
    for(ll s : megu){
        if(s > 0 && s > bestPos){
            aquaa.push_back(s);
            bestPos = s;
        }
        else if(s < 0 && llabs(s) > bestNeg){
            aquaa.push_back(s);
            bestNeg = llabs(s);
        }
    }

    // If there was never a sign‐change, we only have one “record”:
    if(aquaa.size() <= 1){
        // the only contributions are from the last positive record (bestPos)
        // and the last negative record (bestNeg), which go to ans[n] and ans[1].
        ans[1] = bestNeg;
        ans[n] = bestPos;
        for(int i = 1; i <= n; i++){
            cout << ans[i] << "\n";
        }
        return 0;
    }

    // 3) Keep only the points at which the prefix‐sum flips sign
    vector<ll> aqua;
    aqua.reserve(aquaa.size());
    for(int i = 0; i + 1 < (int)aquaa.size(); i++){
        if ((aquaa[i] > 0) != (aquaa[i+1] > 0))
            aqua.push_back(aquaa[i]);
    }
    // always add the final “record”
    aqua.push_back(aquaa.back());

    // 4) Precompute the dm[] = |aqua[i]| + |aqua[i+1]| array and sort it
    vector<ll> dm;
    dm.reserve(aqua.size()-1);
    for(int i = 0; i + 1 < (int)aqua.size(); i++){
        dm.push_back(llabs(aqua[i]) + llabs(aqua[i+1]));
    }
    sort(dm.begin(), dm.end());

    // 5) Sweep through the original a[1..n], splitting each gap a[i+1]-a[i]
    //    optimally between the two sides
    for(int i = 1; i < n; i++){
        ll gap = a[i+1] - a[i];
        // find the largest dm[p] <= gap
        int p = int(upper_bound(dm.begin(), dm.end(), gap) - dm.begin()) - 1;

        if(p == -1){
            // gap smaller than any dm[0]
            if(aqua[0] > 0){
                ans[i]   += min(aqua[0], gap);
                gap      -= min(aqua[0], gap);
                if(gap > 0) ans[i+1] += gap;
            } else {
                ans[i+1] += min(llabs(aqua[0]), gap);
                gap      -= min(llabs(aqua[0]), gap);
                if(gap > 0) ans[i]   += gap;
            }
        }
        else if(p == (int)dm.size()-1){
            // use the very last “flip”
            if(aqua[p] > 0){
                ans[i]   += aqua[p];
                ans[i+1] += llabs(aqua[p+1]);
            } else {
                ans[i]   += aqua[p+1];
                ans[i+1] += llabs(aqua[p]);
            }
        }
        else {
            // take dm[p] fully, then split the rest
            if(aqua[p] > 0){
                ans[i]   +=   aqua[p] + (gap - dm[p]);
                ans[i+1] += llabs(aqua[p+1]);
            } else {
                ans[i]   +=   aqua[p+1];
                ans[i+1] += llabs(aqua[p]) + (gap - dm[p]);
            }
        }
    }

    // 6) add the final dangling bits
    ans[1] += bestNeg;
    ans[n] += bestPos;

    // 7) print
    for(int i = 1; i <= n; i++){
        cout << ans[i] << "\n";
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...