Submission #1354976

#TimeUsernameProblemLanguageResultExecution timeMemory
1354976retardeFood Court (JOI21_foodcourt)C++20
100 / 100
577 ms96360 KiB
#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define int long long
#define all(x) (x).begin(), (x).end()

typedef long double ld;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<bool> vb;
typedef vector<vector<int>> vvi;
typedef vector<vector<bool>> vvb;
typedef vector<vector<ll>> vvll;
typedef vector<string> vs;
typedef vector<vector<string>> vvs;
typedef vector<char> vc;
typedef vector<vector<char>> vvc;
typedef map<int, int> mii;
typedef unordered_map<int, int> umii;

const int mod = 1e9 + 7;
const int inf = INTMAX_MAX / 4;
const bool tc = false;

struct lz {
    int s, m;
    bool operator==(const lz & other) const {
        return (s == other.s && m == other.m);
    }
};
lz sent = {0, (int)-1e18};

lz comb(lz &a, lz &b) {
    if (a == sent) return b;
    if (b == sent) return a;
    lz ans = {a.s + b.s, max(a.m + b.s, b.m)};
    return ans;
}

class st {
    int n;
    vi seg; vector<lz> lazy;

    private:
    void build(int i, int l, int r) {
        if (l > r) return;
        lazy[i] = sent;
        if (l == r) return;
        int mid = (l + r) / 2;
        build(i * 2, l, mid);
        build(i * 2 + 1, mid+1, r);
    }

    void push(int i, int l, int r) {
        if (lazy[i] == sent) return;
        seg[i] = max(seg[i] + lazy[i].s, lazy[i].m);
        if (l == r) {
            lazy[i] = sent;
            return;
        }
        lazy[i * 2] = comb(lazy[i * 2], lazy[i]);
        lazy[i * 2 + 1] = comb(lazy[i * 2 + 1], lazy[i]);
        lazy[i] = sent;
    }

    void update(int i, int l, int r, int ql, int qr, lz tag) {
        push(i, l, r);
        if (r < ql || qr < l) return;
        if (ql <= l && r <= qr) {
            lazy[i] = comb(lazy[i], tag);
            push(i, l, r);
            return;
        }
        int mid = (l + r) / 2;
        update(i * 2, l, mid, ql, qr, tag);
        update(i * 2 + 1, mid + 1, r, ql, qr, tag);
    }

    int query(int i, int l, int r, int qi) {
        push(i, l, r);
        if (l == r) return seg[i];
        int mid = (l + r) / 2;
        if (qi <= mid) return query(i * 2, l, mid, qi);
        else return query(i * 2 + 1, mid + 1, r, qi);
    }

    public:
    st(int qn) {
        n = qn;
        seg.resize(4 * n); lazy.resize(4 * n);
        build(1, 0, n - 1);
    }

    void update(int l, int r, lz tag) {
        update(1, 0, n - 1, l, r, tag);
    }

    int query(int qi) {
        return query(1, 0, n - 1, qi);
    }
};

class st2 {
    int n;
    vector<pii> seg;
    vi lazy;

    private:
    pii merge(pii a, pii b) {
        if (a.fi != b.fi) return min(a, b);
        return {a.fi, min(a.se, b.se)};
    }

    void build(int i, int l, int r, int val) {
        lazy[i] = 0;
        if (l == r) {
            seg[i] = {val, l};
            return;
        }
        int mid = (l + r) / 2;
        build(i * 2, l, mid, val);
        build(i * 2 + 1, mid + 1, r, val);
        seg[i] = merge(seg[i * 2], seg[i * 2 + 1]);
    }

    void push(int i, int l, int r) {
        if (!lazy[i]) return;
        seg[i].fi += lazy[i];
        if (l != r) {
            lazy[i * 2] += lazy[i];
            lazy[i * 2 + 1] += lazy[i];
        }
        lazy[i] = 0;
    }

    void update(int i, int l, int r, int ql, int qr, int val) {
        push(i, l, r);
        if (r < ql || qr < l) return;
        if (ql <= l && r <= qr) {
            lazy[i] += val;
            push(i, l, r);
            return;
        }
        int mid = (l + r) / 2;
        update(i * 2, l, mid, ql, qr, val);
        update(i * 2 + 1, mid + 1, r, ql, qr, val);
        seg[i] = merge(seg[i * 2], seg[i * 2 + 1]);
    }

    pii query(int i, int l, int r, int ql, int qr) {
        push(i, l, r);
        if (r < ql || qr < l) return {inf, inf};
        if (ql <= l && r <= qr) return seg[i];
        int mid = (l + r) / 2;
        return merge(query(i * 2, l, mid, ql, qr), query(i * 2 + 1, mid + 1, r, ql, qr));
    }

    public:
    st2(int qn, int val = 0) {
        n = qn;
        seg.resize(4 * n); lazy.resize(4 * n);
        build(1, 0, n - 1, val);
    }

    void update(int l, int r, int val) {
        update(1, 0, n - 1, l, r, val);
    }

    pii query(int l, int r) {
        return query(1, 0, n - 1, l, r);
    }

    void setv(int idx, int val) {
        int cur = query(idx, idx).fi;
        update(idx, idx, val - cur);
    }
};

struct qr {
    int t, l, r, c, k, a, b;
};

int n, m, q;

inline void solve() {
    cin >> n >> m >> q;

    st Seg(n);
    st2 Tot(n);

    vector<qr> qs;
    vector<vector<pii>> req(n);
    vi ans;

    for (int qq = 0; qq < q; qq++) {
        int t; cin >> t;

        if (t == 1) {
            int l, r, c, k;
            cin >> l >> r >> c >> k;
            l--; r--;

            qs.pb({t, l, r, c, k, -1, -1});

            lz tag = {k, (int)-1e18};
            Seg.update(l, r, tag);
            Tot.update(l, r, k);
        }

        if (t == 2) {
            int l, r, k;
            cin >> l >> r >> k;
            l--; r--;

            qs.pb({t, l, r, -1, k, -1, -1});

            lz tag = {-k, (int)0};
            Seg.update(l, r, tag);
        }

        if (t == 3) {
            int a, b;
            cin >> a >> b;
            a--;

            qs.pb({t, -1, -1, -1, -1, a, b});

            int cur = Seg.query(a);
            int id = ans.size();

            if (cur < b) {
                ans.pb(0);
            }
            else {
                int tot = Tot.query(a, a).fi;
                int idx = tot - (cur - b);
                ans.pb(-1);
                req[a].pb({idx, id});
            }
        }
    }

    for (int i = 0; i < n; i++) {
        sort(all(req[i]));
    }

    st2 Need(n, inf);
    vi ptr(n);

    for (int i = 0; i < n; i++) {
        if (!req[i].empty()) {
            Need.setv(i, req[i][0].fi);
        }
    }

    for (auto e : qs) {
        if (e.t != 1) continue;

        Need.update(e.l, e.r, -e.k);

        while (Need.query(e.l, e.r).fi <= 0) {
            int shop = Need.query(e.l, e.r).se;

            int old = req[shop][ptr[shop]].fi;
            int id = req[shop][ptr[shop]].se;

            ans[id] = e.c;
            ptr[shop]++;

            if (ptr[shop] == (int)req[shop].size()) {
                Need.setv(shop, inf);
            }
            else {
                int nw = req[shop][ptr[shop]].fi;
                Need.update(shop, shop, nw - old);
            }
        }
    }

    for (auto x : ans) {
        cout << x << '\n';
    }
}

void setIO(string s) {
    freopen((s + ".in").c_str(), "r", stdin);
    freopen((s + ".out").c_str(), "w", stdout);
}

signed main() {
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);

    int t = 1;
    if (tc) {
        cin >> t;
    }

    while (t--) {
        solve();
    }
}

Compilation message (stderr)

foodcourt.cpp: In function 'void setIO(std::string)':
foodcourt.cpp:294:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  294 |     freopen((s + ".in").c_str(), "r", stdin);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
foodcourt.cpp:295:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  295 |     freopen((s + ".out").c_str(), "w", stdout);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...