Submission #583574

#TimeUsernameProblemLanguageResultExecution timeMemory
583574JohannTwo Dishes (JOI19_dishes)C++14
5 / 100
691 ms26300 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define pii pair<ll,ll> #define vi vector<ll> #define vpii vector<pii> #define sz(x) (int) (x).size() #define all(x) (x).begin(), (x).end() const ll inf = 1LL << 60; const int MAXN = 1e6 + 7; ll N[2]; ll A[2][MAXN],T[2][MAXN],P[2][MAXN]; struct operation { ll addopt=0; ll maxopt=-inf; }; struct segtree { int size; vector<ll> arr; vector<operation> opt; ll combine(ll ld, ll rd) { return max(ld, rd); } ll calculate(operation o, ll d) { return max(o.maxopt, d + o.addopt); } operation merge(operation ot, operation ob) { return { ot.addopt + ob.addopt, max(ot.maxopt, ob.maxopt) }; } segtree(int N) { size = 1; while (size < N) size *= 2; arr.assign(2*size, 0); opt.assign(2*size, operation()); } void apply(int x, operation & o) { arr[x] = calculate(o, arr[x]); if (x < size) opt[x] = merge(opt[x], o); } void push(int x) { apply(2 * x, opt[x]); apply(2*x+1, opt[x]); opt[x] = operation(); } ll query(int l, int r, int x, int lx, int rx) { if (l <= lx && rx <= r) { return arr[x]; } if (rx <= l || r <= lx) { return -inf; } push(x); int m = ( lx + rx ) / 2; ll lv = query(l, r, 2 * x, lx, m); ll rv = query(l, r, 2*x+1, m, rx); return combine(lv, rv); } void apply(int l, int r, operation o, int x, int lx, int rx) { // add or max if (l <= lx && rx <= r) { apply(x, o); return; } if (rx <= l || r <= lx) { return; } push(x); int m = ( lx + rx ) / 2; apply(l, r, o, 2 * x, lx, m); apply(l, r, o, 2*x+1, m, rx); arr[x] = combine(arr[2 * x], arr[2*x+1]); } void apply(int l, int r, operation o) { apply(l, r, o, 1, 0, size); } ll query(int l, int r){ return query(l, r, 1, 0, size); } }; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> N[0] >> N[1]; for (int j = 0; j < 2; ++j) { for (int i = 0; i < N[j]; ++i) { cin >> A[j][i] >> T[j][i] >> P[j][i]; if (i > 0) A[j][i] += A[j][i-1]; // A ist eine Präfixsumme T[j][i] -= A[j][i]; // Wie viel darf ich vom anderen machen, ich noch Punkte bekomme? } } // Segmentbaum auf N[1] aufgebaut segtree seg = segtree(N[1]+1); // Index shift bei j um 1! // init 0th layer: ll points = 0; priority_queue<pii, vpii, greater<>> q; for (int j = 0; j < N[1]; ++j) { if (T[1][j] >= 0) { points += P[1][j]; q.push({ upper_bound(A[0], A[0] + N[0], T[1][j]) - A[0], j }); } } seg.apply(0, N[1]+1, { points, -inf }); // ernst for (int i = 0; i < N[0]; ++i) { vi cuts; while (!q.empty() && q.top().first == i) { int j = q.top().second; q.pop(); seg.apply(0, j+1, { - P[1][j], -inf }); cuts.push_back(j+1); // for (int i = 0; i <= N[1]; ++i) cout << seg.query(i, i+1) << " "; cout << endl; } if (T[0][i] >= 0) { ll j = upper_bound(A[1], A[1] + N[1], T[0][i]) - A[1]; seg.apply(0, j+1, { P[0][i], -inf }); cuts.push_back(j+1); // for (int i = 0; i <= N[1]; ++i) cout << seg.query(i, i+1) << " "; cout << endl; } for (int x : cuts) { ll v = seg.query(0, x); seg.apply(x, N[1]+1, { 0, v }); // for (int i = 0; i <= N[1]; ++i) cout << seg.query(i, i+1) << " "; cout << endl; } } cout << seg.query(0, N[1]+1) << "\n"; }
#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...