(UPD: 2024-12-04 14:48 UTC) Judge is not working due to Cloudflare incident. (URL) We can do nothing about it, sorry. After the incident is resolved, we will grade all submissions.

Submission #817635

#TimeUsernameProblemLanguageResultExecution timeMemory
817635NothingXDMeetings (IOI18_meetings)C++17
100 / 100
2921 ms457456 KiB
#include "meetings.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef double ld; typedef complex<ld> point; void debug_out(){cerr << endl;} template<typename Head, typename... Tail> void debug_out(Head H, Tail... T){ cerr << H << ' '; debug_out(T...); } #define debug(...) cerr << "(" << #__VA_ARGS__ << "): ", debug_out(__VA_ARGS__) #define F first #define S second #define all(x) x.begin(), x.end() #define MP(x, y) make_pair(x, y) const int maxn = 1e6 + 10; struct Seg{ ll l, r, lazy2; pll lazy1; }; Seg seg[maxn << 2]; void merge(int v) { seg[v].l = seg[v << 1].l; seg[v].r = seg[v << 1 | 1].r; } //void shift(int v, int l, int r); void update1(int v, int l, int r, ll a, ll b){ seg[v].l = a + b * l; seg[v].r = a + b * (r-1); seg[v].lazy1 = {a, b}; } void update2(int v, int l, int r, ll val){ seg[v].l += val; seg[v].r += val; seg[v].lazy1.F += val; seg[v].lazy2 += val; } void shift(int v, int l, int r){ if (seg[v].lazy2 == 0 && seg[v].lazy1.S == -1) return; int mid = (l + r) >> 1; if (seg[v].lazy2 != 0){ update2(v << 1, l, mid, seg[v].lazy2); update2(v << 1 | 1, mid, r, seg[v].lazy2); } if (seg[v].lazy1.S != -1){ update1(v << 1, l, mid, seg[v].lazy1.F, seg[v].lazy1.S); update1(v << 1 | 1, mid, r, seg[v].lazy1.F, seg[v].lazy1.S); } seg[v].lazy1 = {0, -1}; seg[v].lazy2 = 0; } void change(int v, int l, int r, int ql, int qr, ll a, ll b){ // if (v == 1) debug(ql, qr, a, b); if (qr <= l || r <= ql) return; if (!(ql <= l && r <= qr)){ shift(v, l, r); int mid = (l + r) >> 1; change(v << 1, l, mid, ql, qr, a, b); change(v << 1 | 1, mid, r, ql, qr, a, b); } else{ // debug(v, l, r, ql, qr, a, b, seg[v].l, seg[v].r); if (a + b * l <= seg[v].l && a + b * (r-1) <= seg[v].r){ // debug(seg[v].l, seg[v].r, seg[v].mx, seg[v].lazy1.F, seg[v].lazy1.S); update1(v, l, r, a, b); return; } if (a + b * l >= seg[v].l && a + b * (r-1) >= seg[v].r) return; shift(v, l, r); int mid = (l + r) >> 1; change(v << 1, l, mid, ql, qr, a, b); change(v << 1 | 1, mid, r, ql, qr, a, b); } merge(v); //seg[v] = seg[v << 1] + seg[v << 1 | 1]; } void add(int v, int l, int r, int ql, int qr, ll val){ //if (v == 1) debug(ql, qr, val); if (qr <= l || r <= ql) return; if (ql <= l && r <= qr){ // debug(v, l, r, ql, qr, val); update2(v, l, r, val); return; } shift(v, l, r); int mid = (l + r) >> 1; add(v << 1, l, mid, ql, qr, val); add(v << 1 | 1, mid, r, ql, qr, val); merge(v); //seg[v] = seg[v << 1] + seg[v << 1 | 1]; } ll get(int v, int l, int r, int idx){ //if (v == 1) debug(idx); if (l + 1 == r) return seg[v].l; shift(v, l, r); int mid = (l + r) >> 1; if (idx < mid) return get(v << 1, l, mid, idx); else return get(v << 1 | 1, mid, r, idx); } const int lg = 20; const ll inf = 1e18; int n, q, h[maxn], queryl[maxn], queryr[maxn]; ll ans[maxn]; pii rmq[lg][maxn]; vector<pair<pii,int>> Q[maxn]; pii getmx(int l, int r){ r++; int x = 31 - __builtin_clz(r-l); return max(rmq[x][l], rmq[x][r-(1<<x)]); } void carttree(int l, int r){ if (r < l) return; int mid = getmx(l, r).S; mid = abs(mid); carttree(l, mid-1); carttree(mid+1, r); // debug(x, y); for (auto [tmp, idx]: Q[mid]){ ans[idx] = min(ans[idx], get(1, 0, n, tmp.S) + 1ll * (mid-tmp.F+1) * h[mid]); } add(1, 0, n, mid, r+1, 1ll * (mid-l+1) * h[mid]); if (l == mid) return; ll tmp = get(1, 0, n, mid-1); tmp -= 1ll * (mid-1) * h[mid]; change(1, 0, n, mid, r+1, tmp, h[mid]); } void solve(bool flg){ vector<pii> val; for (int i = 0; i < n; i++){ Q[i].clear(); } for (int i = 1; i < 4*maxn; i++){ seg[i].l = 0; seg[i].r = 0; seg[i].lazy1 = {0, -1}; seg[i].lazy2 = 0; } for (int i = 0; i < n; i++){ if (!flg){ rmq[0][i] = {h[i], i}; } else{ rmq[0][i] = {h[i], -i}; } } for (int i = 1; i < lg; i++){ for (int j = 0; j + (1 << i) <= n; j++){ rmq[i][j] = max(rmq[i-1][j], rmq[i-1][j+(1<<(i-1))]); } } for (int i = 0; i < q; i++){ int mx = abs(getmx(queryl[i], queryr[i]).S); Q[mx].push_back({{queryl[i], queryr[i]}, i}); } carttree(0, n-1); } vector<ll> minimum_costs(vector<int> H, vector<int> L, vector<int> R) { n = H.size(); q = L.size(); for (int i = 0; i < n; i++){ h[i] = H[i]; } for (int i = 0; i < q; i++){ queryl[i] = L[i]; queryr[i] = R[i]; ans[i] = inf; } solve(false); // debug("----------------"); // for (int i = 0; i < q; i++) debug(i, ans[i]); for (int i = 0; i < q; i++){ queryl[i] = n-R[i]-1; queryr[i] = n-L[i]-1; } for (int i = 0; i < n/2; i++){ swap(h[i], h[n-i-1]); } solve(true); vector<ll> res; for (int i = 0; i < q; i++) res.push_back(ans[i]); return res; }
#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...