Submission #546909

#TimeUsernameProblemLanguageResultExecution timeMemory
546909Ooops_sorryArranging Tickets (JOI17_arranging_tickets)C++14
100 / 100
5455 ms39684 KiB
#include<bits/stdc++.h> using namespace std; #define int long long #define pb push_back #define ld double #define ll __int128 mt19937 rnd(51); const int INF = 1e14 + 100; struct st { vector<int> t, add, arr; void build(int v, int l, int r) { if (l == r) { t[v] = arr[l]; return; } int m = (l + r) / 2; build(2 * v, l, m), build(2 * v + 1, m + 1, r); } st(vector<int> a) { int n = a.size(); arr = a; t.resize(4 * n); add.resize(4 * n); build(1, 0, n - 1); } void push(int v) { t[v] += add[v]; if (v * 2 < add.size()) { add[v * 2] += add[v]; add[v * 2 + 1] += add[v]; } add[v] = 0; } void update(int v, int tl, int tr, int l, int r, int val) { if (l > r) return; if (tl == l && tr == r) { add[v] += val; return; } int tm = (tl + tr) / 2; update(2 * v, tl, tm, l, min(r, tm), val), update(2 * v + 1, tm + 1, tr, max(l, tm + 1), r, val); } int get(int v, int l, int r, int pos) { push(v); if (l == r) { return t[v]; } int m = (l + r) / 2; if (pos <= m) { return get(2 * v, l, m, pos); } else { return get(2 * v + 1, m + 1, r, pos); } } }; signed main() { #ifdef LOCAL freopen("input.txt", "r", stdin); #endif // LOCAL ios_base::sync_with_stdio(0); cin.tie(0); int n, q; cin >> n >> q; vector<int> a(q), b(q), c(q), pr(n + 1), d(n); vector<vector<pair<int,int>>> need(n); for (int i = 0; i < q; i++) { cin >> a[i] >> b[i] >> c[i]; a[i]--, b[i]--; if (a[i] > b[i]) swap(a[i], b[i]); b[i]--; pr[a[i]] += c[i], pr[b[i] + 1] -= c[i]; need[a[i]].pb({b[i], c[i]}); } int sum = 0; for (int i = 0; i < n; i++) { sum += pr[i]; d[i] = sum; } int l = 0, r = INF; int val = *max_element(d.begin(), d.end()); while (r - l > 1) { int mid = (r + l) / 2; bool ok = 0, bad = 0; if (val <= mid) { r = mid; continue; } for (int m = val - mid; m <= val - mid + 1; m++) { for (int j = 0; j < n; j++) { d[j] += m; } st t(d); for (int j = 0; j < n; j++) { d[j] -= m; } multiset<pair<int,int>> st; int cnt = 0; for (int i = 0; i < n; i++) { for (auto to : need[i]) { st.insert(to); } int val = t.get(1, 0, n - 1, i); while (val > mid) { if (st.size() == 0) { bad = 1; break; } auto to = *st.rbegin(); st.erase(st.find(to)); if (2 * to.second >= val - mid) { int need = (val - mid + 1) / 2; t.update(1, 0, n - 1, i, to.first, -2 * need); to.second -= need; if (to.second > 0) { st.insert(to); } cnt += need; break; } else { t.update(1, 0, n - 1, i, to.first, -2 * to.second); cnt += to.second; val -= 2 * to.second; } } if (bad) { break; } } if (cnt <= m && !bad) { ok = 1; break; } } if (ok) { r = mid; } else { l = mid; } } cout << r << endl; return 0; }
#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...