Cod sursa(job #2427728)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 1 iunie 2019 22:04:55
Problema Fabrica Scor 12
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.7 kb
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <functional>

using namespace std;

typedef long long ll;

struct E1 {
        ll t, cy;
};

bool operator < (E1 a, E1 b) {
        return a.t > b.t;
}


int main() {
        freopen ("fabrica.in", "r", stdin);
        freopen ("fabrica.out", "w", stdout);
        ll len, n, m;
        cin >> len >> n >> m;

        priority_queue <E1> Q;
        for (ll i = 0; i < n; i++) {
                ll cy;
                cin >> cy;
                Q.push({cy, cy});
        }

        vector <ll> t(len);
        for (ll i = 0; i < len; i++) {
                auto it = Q.top();
                t[i] = it.t;
                Q.pop();
                Q.push({it.t + it.cy, it.cy});
        }

        vector <ll> cy(m);
        for (ll i = 0; i < m; i++) {
                cin >> cy[i];
        }
        sort(cy.begin(), cy.end());

        function <bool (ll)> ok = [&] (ll T) {
                if (T < t[len - 1]) {
                        return 0;
                }

                priority_queue <E1> Join;
                for (ll i = 0; i < m; i++) {
                        Join.push({0, cy[i]});
                }
                priority_queue <ll> Available;

                for (auto &when : t) {
                        while (!Join.empty()) {
                                auto it = Join.top();
                                if (it.t <= when) {
                                        Join.pop();
                                        Available.push(it.cy);
                                } else {
                                        break;
                                }
                        }
                        while (!Available.empty()) {
                                auto it = Available.top();
                                if (it + when > T) {
                                        Available.pop();
                                } else {
                                        break;
                                }
                        }
                        if (Available.empty()) {
                                return 0;
                        }
                        auto it = Available.top();
                        Join.push({when + it, it});
                        Available.top();
                }
                return 1;
        };

        ll res = 0;
        for (ll step = (1 << 30); step > 0; step /= 2) {
                if (ok(res + step) == 0) {
                        res += step;
                }
        }
        res++;
        cout << t[len - 1] << " " << res << "\n";

        return 0;
}