제출 #1260553

#제출 시각아이디문제언어결과실행 시간메모리
1260553patgraArranging Tickets (JOI17_arranging_tickets)C++20
100 / 100
1114 ms19064 KiB
#include <bits/stdc++.h>

#define rep(a,b,c) for(auto a = (b); a != (c); a++)
#define repD(a,b,c) for(auto a = (b); a != (c); a--)
#define repIn(a, b) for(auto& a : (b))
#define repIn2(a, b, c) for(auto& [a, b] : (c))

constexpr bool dbg = 1;
#define DEBUG if constexpr(dbg)
#define DC DEBUG std::cerr
#define eol std::endl

#define ll long long
#define pb push_back

using namespace std;

#define int ll

int32_t main() {
    ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    int n, m;
    cin >> n >> m;
    vector<pair<pair<int, int>, int>> v;
    map<pair<int, int>, int> mp;
    rep(i, 0, m) {
        int a, b, c;
        cin >> a >> b  >> c;
        a--; b--;
        if(a > b) swap(a, b);
        b--;
        mp[{a, b}] += c;
    }
    repIn(i, mp) v.pb(i);
    m = v.size();

    pair<int, int> mx = {-1, -1};
    vector<int> over;
    vector<pair<int, int>> begs, ends;
    repIn2(ab, c, v) begs.pb({ab.first, c}), ends.pb({ab.second, c});
    ranges::sort(begs), ranges::sort(ends);
    int bi = 0, ei = 0;
    int cur = 0;
    rep(i, 0, n) {
        while(bi < m && begs[bi].first <= i) cur += begs[bi++].second;
        while(ei < m && ends[ei].first < i) cur -= ends[ei++].second;
        mx = max(mx, {cur, i});
        over.pb(cur);
    }

    int l = 0, r = mx.first;
    while(r - l > 1) {
        int md = (l + r) / 2;
        bool works = false;
        rep(out, mx.first - md, mx.first - md + 2) {
            // over + out - 2x <= md
            // 2x >= over + out - md
            // x >= (over + out - md) / 2
            priority_queue<pair<int, int>> q;
            int vi = 0, turned = 0;
            vector<pair<int, int>> whereTo;
            bool g = true;
            rep(i, 0, mx.second + 1) {
                while(vi < m && v[vi].first.first <= i) {
                    if(v[vi].first.second >= mx.second) q.push({v[vi].first.second, v[vi].second});
                    vi++;
                }
                int need = (over[i] + out - md + 1) / 2;
                while(q.size() && turned < need) {
                    auto [end, val] = q.top();
                    q.pop();
                    if(val <= need - turned) {
                        turned += val;
                        whereTo.pb({end, val});
                    }
                    else {
                        whereTo.pb({end, need - turned});
                        val -= need - turned;
                        turned = need;
                        q.push({end, val});
                    }
                }
                if(turned < need) { g = false; break; }
            }
            if(!g) continue;
            ranges::sort(whereTo);
            int wti = 0;
            rep(i, mx.second + 1, n) {
                while(wti < (int)whereTo.size() && whereTo[wti].first < i) turned -= whereTo[wti++].second;
                int need = (over[i] + out - md + 1) / 2;
                if(turned < need) { g = false; break; }
            }
            if(!g) continue;
            works = true;
            // TODO maybe check n?
            break;
        }
        (works ? r : l) = md;
    }
    cout << r << eol;
}

#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...