Submission #1317626

#TimeUsernameProblemLanguageResultExecution timeMemory
1317626foxsergNile (IOI24_nile)C++20
100 / 100
744 ms86524 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; const ll inf = 1e18 + 1e16; struct SegmentTree { struct Matrix { vector <vector <ll>> arr; Matrix() { arr.resize(3); for (int i = 0; i < 3; ++i) arr[i].resize(3, 0); } Matrix(ll x) { arr.resize(3); for (int i = 0; i < 3; ++i) arr[i].resize(3); arr[0][0] = x; arr[0][1] = inf; arr[0][2] = inf; arr[1][0] = 0; arr[1][1] = inf; arr[1][2] = inf; arr[2][0] = inf; arr[2][1] = 0; arr[2][2] = inf; } }; int n; vector <Matrix> t; SegmentTree() = default; SegmentTree(int n): n(n) { t.resize(4 * n); } ll calc(vector <vector <ll>> &a, int i, vector <vector <ll>> &b, int j) { return min({a[i][0] + b[0][j], a[i][1] + b[1][j], a[i][2] + b[2][j]}); } Matrix merge(Matrix &a, Matrix &b) { Matrix c; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { c.arr[i][j] = calc(a.arr, i, b.arr, j); } } return c; } void build(int v, int l, int r, vector <int> &A) { if (r - l == 1) { t[v] = Matrix(A[l]); return; } int m = (l + r) / 2; build(2 * v + 1, l, m, A); build(2 * v + 2, m, r, A); t[v] = merge(t[2 * v + 2], t[2 * v + 1]); } void build(vector <int> &A) { build(0, 0, n, A); } void update(int v, int l, int r, int pos, int d, int x) { if (r - l == 1) { t[v].arr[0][d] = x; return; } int m = (l + r) / 2; if (pos < m) { update(2 * v + 1, l, m, pos, d, x); } else { update(2 * v + 2, m, r, pos, d, x); } t[v] = merge(t[2 * v + 2], t[2 * v + 1]); } void update(int pos, int d, int x) { update(0, 0, n, pos, d, x); } ll get() { return t[0].arr[0][0]; } }; struct quest { int ind; int d; int t; // 0 - update1, 1 - update2, 2 - get quest() = default; quest(int ind, int d, int t): ind(ind), d(d), t(t) {} bool operator<(const quest &oth) const { return tie(d, t) < tie(oth.d, oth.t); } }; vector <ll> calculate_costs(vector <int> W, vector <int> A, vector <int> B, vector <int> E) { int n = A.size(); int p[n]; iota(p, p + n, 0); sort(p, p + n, [&](int i, int j) { return W[i] < W[j]; }); vector <int> nW(n); vector <int> nA(n); vector <int> nB(n); for (int i = 0; i < n; ++i) { nW[i] = W[p[i]]; nA[i] = A[p[i]]; nB[i] = B[p[i]]; } W = move(nW); A = move(nA); B = move(nB); ll sm = 0; for (int i = 0; i < n; ++i) sm += B[i]; for (int i = 0; i < n; ++i) A[i] -= B[i]; vector <quest> qs; if (n >= 2) { qs.push_back(quest(1, W[1] - W[0], 0)); } for (int i = 2; i < n; ++i) { qs.push_back(quest(i, W[i] - W[i - 2], 1)); qs.push_back(quest(i, W[i] - W[i - 1], 0)); } int q = E.size(); vector <ll> R(q); for (int i = 0; i < q; ++i) { qs.push_back(quest(i, E[i], 2)); } SegmentTree t(n); t.build(A); sort(qs.begin(), qs.end()); for (quest e : qs) { if (e.t <= 1) { t.update(e.ind, e.t + 1, e.t * A[e.ind - 1]); } else { R[e.ind] = t.get() + sm; } } return R; }
#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...