제출 #413877

#제출 시각아이디문제언어결과실행 시간메모리
413877usachevd0모임들 (IOI18_meetings)C++14
4 / 100
93 ms28572 KiB
#include <bits/stdc++.h> #ifndef LOCAL #include "meetings.h" #endif using namespace std; #define fi first #define se second #define mp make_pair #define pb push_back #define all(a) (a).begin(), (a).end() #define Time (clock() * 1.0 / CLOCKS_PER_SEC) using ll = long long; using ull = unsigned long long; using pii = pair<int, int>; using pil = pair<int, ll>; using pli = pair<ll, int>; using pll = pair<ll, ll>; using ld = long double; template<typename T1, typename T2> bool chkmin(T1& x, T2 y) { return y < x ? (x = y, true) : false; } template<typename T1, typename T2> bool chkmax(T1& x, T2 y) { return y > x ? (x = y, true) : false; } void debug_out() { cerr << endl; } template<typename T1, typename... T2> void debug_out(T1 A, T2... B) { cerr << ' ' << A; debug_out(B...); } template<typename T> void mdebug_out(T* a, int n) { for (int i = 0; i < n; ++i) cerr << a[i] << ' '; cerr << endl; } #ifdef LOCAL #define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__) #define mdebug(a, n) cerr << #a << ": ", mdebug_out(a, n) #else #define debug(...) 1337 #define mdebug(a, n) 1337 #endif template<typename T> ostream& operator << (ostream& stream, const vector<T>& v) { for (auto& x : v) stream << x << ' '; return stream; } template<typename T1, typename T2> ostream& operator << (ostream& stream, const pair<T1, T2>& p) { return stream << p.first << ' ' << p.second; } template<typename T> ostream& operator << (ostream& stream, const deque<T>& v) { for (auto& x : v) stream << x << ' '; return stream; } const int INF32 = 1e9; const ll INF64 = 1e18; const int maxN = 750005; int n, Q; int a[maxN]; int randY[maxN], irandY[maxN]; vector<int> que[maxN]; namespace sgt { const int logN = 20; const int N = 1 << logN; pii t[2 * N]; void build(bool rev = false) { for (int i = 0; i < n; ++i) t[i + N] = (!rev ? mp(a[i], randY[i]) : mp(a[i], -randY[i])); for (int i = N - 1; i >= 1; --i) { t[i] = max(t[i << 1], t[i << 1 | 1]); } } int argmax(int l, int r) { pii ans = {-INF32, -INF32}; for (l += N, r += N; l <= r; l >>= 1, r >>= 1) { if (l & 1) chkmax(ans, t[l++]); if (~r & 1) chkmax(ans, t[r--]); } return irandY[labs(ans.se)]; } } struct line { int k; ll b; line() {} line(ll _k, ll _b): k(_k), b(_b) {} ll f(ll x) { return k * x + b; } }; ostream& operator << (ostream& stream, const line& l) { return stream << l.k << "i + " << l.b; } double intersect(const line& lhs, const line& rhs) { return (rhs.b - lhs.b) / (double)(lhs.k - rhs.k); } struct DS { ll delta; deque<line> val; deque<int> L; int R; DS() { delta = 0; val.clear(); L.clear(); } DS(ll x, int l) { delta = 0; val = {{0, x}}; L = {l}; } void clear() { delta = 0; val.clear(); L.clear(); } int size() { return val.size(); } void pushBack(int i, ll x) { x -= delta; val.push_back({0, x}); L.push_back(i); } void pushFront(int i, ll x) { x -= delta; val.push_front({0, x}); L.push_front(i); } void add(ll d) { delta += d; } void relaxPrefix(line e) { if (val.empty()) return; e.b -= delta; if (val[0].f(L[0]) <= e.f(L[0])) return; int l = L[0]; while (!val.empty() && val[0].f(L[0]) > e.f(L[0])) { int r = (val.size() > 1 ? L[1] - 1 : R); if (val[0].f(r) >= e.f(r)) { val.pop_front(); L.pop_front(); } else { L[0] = ceil(intersect(e, val[0])); break; } } val.push_front(e); L.push_front(l); } ll f(int i) { // if (val.empty()) return 0; int t = upper_bound(all(L), i) - L.begin() - 1; if (t < 0) return 0; return val[t].f(i) + delta; } }; vector<ll> minimum_costs(vector<int> _a, vector<int> ql, vector<int> qr) { n = _a.size(), Q = ql.size(); for (int i = 0; i < n; ++i) a[i] = _a[i]; mt19937 rng(228); iota(randY, randY + n, 0); shuffle(randY, randY + n, rng); for (int i = 0; i < n; ++i) irandY[randY[i]] = i; vector<ll> ans(Q, INF64); for (int rot = 0; rot < 2; ++rot) { for (int i = 0; i < n; ++i) { que[i].clear(); // PP[i].clear(); } sgt::build(rot); for (int i = 0; i < Q; ++i) { int j = sgt::argmax(ql[i], qr[i]); que[j].push_back(i); } function<DS(int, int)> solve = [&](int L, int R) { if (L > R) return DS(); int I = sgt::argmax(L, R); ll M = a[I]; // debug(L, I, R); // auto& P = PP[I]; // int IL = solve(L, I - 1); // auto& PL = PP[IL]; // int IR = solve(I + 1, R); // auto& PR = PP[IR]; DS P; P.R = R; DS PL = solve(L, I - 1); DS PR = solve(I + 1, R); for (int q : que[I]) { int l = ql[q], r = qr[q]; chkmin(ans[q], PR.f(r) + M * (I - l + 1)); } PR.add(M * (I - L + 1)); PR.relaxPrefix({M, PL.f(I - 1) - M * (I - 1)}); if (PR.size() <= PL.size()) { swap(P, PL); P.R = R; P.pushBack(I, P.f(I - 1) + M); for (int i = I + 1, t = 0; i <= R; ++i) { while (t + 1 < PR.size() && PR.L[t + 1] <= i) ++t; P.pushBack(i, PR.val[t].f(i) + PR.delta); } PR.clear(); } else { swap(P, PR); P.R = R; P.pushFront(I, PL.f(I - 1) + M); for (int i = I - 1, t = PL.size() - 1; i >= L; --i) { while (PL.L[t] > i) --t; P.pushFront(i, PL.val[t].f(i) + PL.delta); } PL.clear(); } // debug(L, I, R); // debug(P.val); // debug(P.L); // for (int i = L; i <= R; ++i) // cerr << P.f(i) << ' '; // cerr << endl; // debug(ans); return P; }; auto P = solve(0, n - 1); P.clear(); reverse(a, a + n); for (int i = 0; i < Q; ++i) { ql[i] = n - ql[i] - 1; qr[i] = n - qr[i] - 1; swap(ql[i], qr[i]); } } return ans; } #ifdef LOCAL int read_int() { int x; if (scanf("%d", &x) != 1) { fprintf(stderr, "Error while reading input\n"); exit(1); } return x; } int32_t main() { #ifdef LOCAL freopen("in", "r", stdin); #endif ios::sync_with_stdio(0); cin.tie(0); int N = read_int(); int Q = read_int(); std::vector<int> H(N); for (int i = 0; i < N; ++i) { H[i] = read_int(); } std::vector<int> L(Q), R(Q); for (int j = 0; j < Q; ++j) { L[j] = read_int(); R[j] = read_int(); } std::vector<long long> C = minimum_costs(H, L, R); for (size_t j = 0; j < C.size(); ++j) { printf("%lld\n", C[j]); } return 0; return 0; } #endif
#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...