Submission #781863

#TimeUsernameProblemLanguageResultExecution timeMemory
781863TeaTimeTwo Dishes (JOI19_dishes)C++17
100 / 100
5521 ms432332 KiB
#include <iostream> #include <vector> #include <set> #include <algorithm> #include <cmath> #include <cassert> using namespace std; typedef long long ll; typedef long double ld; #define fastInp cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(0); const ll SZ = 1'000'100, INF = 2'000'000'000'000'000'000; #define int ll ll n, m; struct el { ll a, s, p; }; vector<el> vec1, vec2; vector<ll> pref1, pref2; struct point { ll x, y, val; }; vector<point> blue, red; ll seg[SZ * 8], psh[SZ * 8]; void push(int v) { seg[v * 2 + 1] += psh[v]; seg[v * 2 + 2] += psh[v]; psh[v * 2 + 1] += psh[v]; psh[v * 2 + 2] += psh[v]; psh[v] = 0; } void upd(int v, int l, int r, int askl, int askr, ll val) { push(v); if (l >= askr || r <= askl) return; if (askl <= l && r <= askr) { seg[v] += val; psh[v] += val; return; } int mid = (l + r) / 2; upd(v * 2 + 1, l, mid, askl, askr, val); upd(v * 2 + 2, mid, r, askl, askr, val); seg[v] = max(seg[v * 2 + 1], seg[v * 2 + 2]); } void upd(int v, int l, int r, int pos, ll val) { push(v); if (l == r - 1) { seg[v] = val; } else { int mid = (l + r) / 2; if (pos < mid) { upd(v * 2 + 1, l, mid, pos, val); } else { upd(v * 2 + 2, mid, r, pos, val); } seg[v] = max(seg[v * 2 + 1], seg[v * 2 + 2]); } } ll ask(int v, int l, int r, int askl, int askr) { push(v); if (l >= askr || r <= askl) return -INF; if (askl <= l && r <= askr) return seg[v]; int mid = (l + r) / 2; return max(ask(v * 2 + 1, l, mid, askl, askr), ask(v * 2 + 2, mid, r, askl, askr)); } vector<point> points[SZ]; bool cmp(point a, point b) { return a.y < b.y; } signed main() { fastInp; cin >> n >> m; vec1.resize(n); vec2.resize(m); pref1.push_back(0); for (auto &c : vec1) { cin >> c.a >> c.s >> c.p; pref1.push_back(pref1.back() + c.a); } pref2.push_back(0); for (auto &c : vec2) { cin >> c.a >> c.s >> c.p; pref2.push_back(pref2.back() + c.a); } for (int i = 0; i < SZ; i++) { seg[i] = -INF; } upd(0, 0, SZ, 0, 0); // x is vec1 // y is vec2 ll ans = 0, prefsum = 0; for (int i = 0; i < n; i++) { prefsum += vec1[i].a; ll left = vec1[i].s - prefsum; if (left < 0) continue; int ind = upper_bound(pref2.begin(), pref2.end(), left) - pref2.begin() - 1; assert(ind >= 0); blue.push_back({i + 1, ind, vec1[i].p}); // above or on the lattice path } prefsum = 0; for (int i = 0; i < m; i++) { prefsum += vec2[i].a; ll left = vec2[i].s - prefsum; if (left < 0) continue; int ind = upper_bound(pref1.begin(), pref1.end(), left) - pref1.begin() - 1; assert(ind >= 0); red.push_back({ind, i + 1, vec2[i].p}); // under or on the lattice path blue.push_back({ind + 1, i, -vec2[i].p}); // above or on the lattice path ans += vec2[i].p; } for (auto c : blue) { points[c.x].push_back(c); if (c.x != 0) points[c.x - 1].push_back({c.x - 1, c.y + 1, 0}); } points[n].push_back({n, m, 0}); for (int i = 0; i < SZ; i++) { sort(points[i].begin(), points[i].end(), cmp); vector<point> cur; for (auto c : points[i]) { if (!cur.empty() && cur.back().y == c.y) { cur.back().val += c.val; } else { cur.push_back(c); } } points[i] = cur; for (auto c : points[i]) { upd(0, 0, SZ, 0, c.y + 1, c.val); ll q = ask(0, 0, SZ, 0, c.y + 1); upd(0, 0, SZ, c.y, q); } } cout << ans + ask(0, 0, SZ, m, m + 1); 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...