Submission #426029

#TimeUsernameProblemLanguageResultExecution timeMemory
426029PetiMeetings (IOI18_meetings)C++14
60 / 100
5604 ms335008 KiB
#include <bits/stdc++.h> #include "meetings.h" #pragma GCC optimize("Ofast") using namespace std; const long long INF = (long long)1e18; struct segment_tree{ vector<int> st, v; int maxn; int get(int x, int y){ if(x == maxn) return y; if(y == maxn) return x; return v[x] >= v[y] ? x : y; } void init(vector<int> ert, int n){ maxn = n; while(maxn != (maxn&(-maxn))) maxn += (maxn&(-maxn)); v = ert; st.resize(maxn<<1, maxn); iota(st.begin()+maxn, st.begin()+maxn+n, 0); for(int i = maxn-1; i > 0; i--) st[i] = get(st[2*i], st[2*i+1]); } int query(int s, int e, int x, int l, int r){ if(e <= l || r <= s) return maxn; if(s <= l && r <= e) return st[x]; int m = (l+r)/2; return get(query(s, e, 2*x, l, m), query(s, e, 2*x+1, m, r)); } int query(int l, int r){ return query(l, r, 1, 0, maxn); } }; struct egyenes{ long long m, b; egyenes(){} egyenes(long long m, long long b) : m(m), b(b) {} long long ertek(long long x) { return m*x+b; } }; struct lichao_tree{ vector<egyenes> st; vector<long long> prop; int maxn; void init(int n){ maxn = n; while(maxn != (maxn&(-maxn))) maxn += (maxn&(-maxn)); st.assign(maxn<<1, egyenes(0, INF)); prop.assign(maxn<<1, 0); } void propagate(int x){ st[x].b += prop[x]; if(x < maxn){ prop[2*x] += prop[x]; prop[2*x+1] += prop[x]; } prop[x] = 0; } void add(egyenes e, int x, int l, int r){ if(e.m == 0ll) return; propagate(x); int m = (l+r)/2; bool bal = e.ertek(l) < st[x].ertek(l); bool koz = e.ertek(m) < st[x].ertek(m); if(koz) swap(st[x], e); if(l+1 == r) return; if(bal == koz) add(e, 2*x+1, m, r); else add(e, 2*x, l, m); } void update(int s, int e, egyenes eg, int x, int l, int r){ propagate(x); if(e <= l || r <= s) return; if(s <= l && r <= e){ add(eg, x, l, r); return; } int m = (l+r)/2; update(s, e, eg, 2*x, l, m); update(s, e, eg, 2*x+1, m, r); } void update(int l, int r, egyenes e) { update(l, r, e, 1, 0, maxn); } void update_lines(int s, int e, long long c, int x, int l, int r){ propagate(x); if(e <= l || r <= s) return; if(s <= l && r <= e){ prop[x] += c; return; } int m = (l+r)/2; update_lines(s, e, c, 2*x, l, m); update_lines(s, e, c, 2*x+1, m, r); } void update_lines(int l, int r, long long c) { update_lines(l, r, c, 1, 0, maxn); } long long query(int ind, int x, int l, int r){ propagate(x); if(l+1 == r) return st[x].ertek(ind); int m = (l+r)/2; if(ind < m) return min(st[x].ertek(ind), query(ind, 2*x, l, m)); return min(st[x].ertek(ind), query(ind, 2*x+1, m, r)); } long long query(int x) { return query(x, 1, 0, maxn); } }; struct adat{ int ind, l, r; }; /*struct node{ int l, r, lc, rc; long long ert; vector<adat> querys; node *L = nullptr, *R = nullptr; node(){} node(node *L, node *R, int l, int r, int lc, int rc) : L(L), R(R), l(l), r(r), lc(lc), rc(rc) {}; }; typedef node* gnode;*/ struct gnode{ int l, r, lc, rc; long long ert; }; segment_tree maxST; lichao_tree lichao; vector<int> h; /*void kiir(gnode p){ cout<<"node: ("<<(p->l)<<", "<<(p->r)<<") ert: "<<p->ert<<" cl: "<<p->lc<<" cr: "<<p->rc<<"\n"; }*/ vector<vector<adat>> vegek((int)1e6); vector<long long> meg; int starts[(int)1e6]; vector<adat> buffer[(int)1e6]; void add_node(gnode os, gnode p, int ind){ long long ossz = (long long)(p.r-p.l)*p.rc; if(h[p.l] > p.rc) ossz += (long long)(h[p.l] - p.rc); lichao.update_lines(p.r, os.r, ossz); lichao.update(p.r, os.r, {p.rc, p.ert-(long long)p.rc*p.r}); return; } long long build(int l, int r, int lc, int rc, int len){ if(l+1 == r){ for(adat d : vegek[l]){ int m = lower_bound(starts, starts+len, d.l)-starts; if(m == len) continue; buffer[m].push_back(d); } return h[l]; } int m = maxST.query(l, r); int c = h[m]; starts[len] = l; buffer[len].clear(); if(m == l) m++; long long lb = build(l, m, lc, c, len+1); long long rb = build(m, r, c, rc, len+1); long long ert = min(lb + (long long)(r-m)*c, rb + (long long)(m-l)*c); add_node({l, r, lc, rc, ert}, {l, m, lc, c, lb}, len); for(adat d : buffer[len]){ meg[d.ind] = min(meg[d.ind], lichao.query(d.r+1) + (long long)(l-d.l)*lc); } return ert; } /*void bejar(gnode p, int len){ if(p->l+1 == p->r){ return; } bejar(p->L, len); bejar(p->R, len+1); }*/ std::vector<long long> minimum_costs(std::vector<int> H, std::vector<int> L, std::vector<int> R) { H.push_back((int)1e9+1); H.insert(H.begin(), (int)1e9+1); int n = (int)H.size(); int q = (int)L.size(); h = H; meg.assign(q, INF); vegek.assign((int)1e6, vector<adat>()); maxST.init(H, n); lichao.init(n); for(int i = 0; i < q; i++) vegek[R[i]+2].push_back({i, L[i]+1, R[i]+1}); build(0, n, 0, 0, 0); for(int i = 0; i < q; i++) vegek[R[i]+2].clear(); reverse(h.begin(), h.end()); maxST.init(h, n); for(int i = 0; i < q; i++) vegek[n-L[i]-1].push_back({i, n-R[i]-2, n-L[i]-2}); build(0, n, 0, 0, 0); return meg; }
#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...