Submission #236311

#TimeUsernameProblemLanguageResultExecution timeMemory
236311lycMeetings (IOI18_meetings)C++14
60 / 100
1236 ms786436 KiB
#include "meetings.h" #include <bits/stdc++.h> using namespace std; #define TRACE(x) cout << #x << " :: " << x << endl; #define _ << " " << #define FOR(i,a,b) for(int i=(a);i<=(b);++i) #define RFOR(i,a,b) for(int i=(a);i>=(b);--i) #define SZ(x) ((int)(x).size()) #define ALL(x) (x).begin(),(x).end() typedef long long ll; const int mxN = 750005; const int lgN = 19; const int mxQ = 750005; int N, Q; vector<int> H; struct SparseTable { int A[mxN][lgN]; void init(vector<int>& H) { FOR(i,0,N-1){ A[i][0] = i; } FOR(k,1,lgN){ FOR(i,0,N-(1<<k)){ int p = A[i][k-1], q = A[i+(1<<(k-1))][k-1]; A[i][k] = (H[p] > H[q] ? p : q); } } } int query(int l, int r) { int k = floor(log2(r-l+1)); int i = A[l][k], j = A[r-(1<<k)+1][k]; return H[i] > H[j] ? i : j; } } st; struct Query { int l, r, i; }; vector<Query> query[mxQ]; vector<ll> ans; ll f(int x, ll m, ll c) { return x*m + c; } struct SegmentTree { struct Node { ll vl, vr, tagM, tagC, add; bool tag; } D[4*mxN]; int n; void build(int _n) { n = _n; fill_n(D,4*n,(Node){0,0,0,0,0,0}); } void replace(int s, int e, int p, ll m, ll c) { D[p].vl = f(s,m,c); D[p].vr = f(e,m,c); D[p].tagM = m; D[p].tagC = c; D[p].add = 0; D[p].tag = true; } void add(int p, ll v) { D[p].vl += v; D[p].vr += v; D[p].add += v; } void prop(int s, int e, int p) { if (D[p].tag) { if (s != e) { int mid = (s+e)/2; replace(s,mid,p<<1,D[p].tagM,D[p].tagC); replace(mid+1,e,p<<1|1,D[p].tagM,D[p].tagC); } D[p].tag = false; } if (D[p].add) { if (s != e) { add(p<<1,D[p].add); add(p<<1|1,D[p].add); } D[p].add = 0; } } void update(int s, int e, int p, int x, int y, ll m, ll c, ll v) { if (x > y) return; if (s >= x && e <= y) { if (f(s,m,c) <= D[p].vl + v && f(e,m,c) <= D[p].vr + v) return replace(s,e,p,m,c); if (D[p].vl + v < f(s,m,c) && D[p].vr + v < f(e,m,c)) return add(p,v); } int mid = (s+e)/2; assert(s != e); prop(s,e,p); if (mid >= x) update(s,mid,p<<1,x,y,m,c,v); if (mid < y) update(mid+1,e,p<<1|1,x,y,m,c,v); D[p].vl = D[p<<1].vl; D[p].vr = D[p<<1].vr; } inline void update(int x, int y, ll m, ll c, ll v) { return update(0,N-1,1,x,y,m,c,v); } ll query(int s, int e, int p, int x) { if (s == e) { return D[p].vl; } else { int mid = (s+e)/2; prop(s,e,p); if (x <= mid) return query(s,mid,p<<1,x); else return query(mid+1,e,p<<1|1,x); } } inline ll query(int x) { return query(0,N-1,1,x); } } fixr, fixl; void solve(int l, int r) { if (l > r) return; int p = st.query(l,r); solve(l,p-1); solve(p+1,r); for (Query q : query[p]) { ans[q.i] = (ll) (q.r-q.l+1) * H[p]; if (q.l < p) ans[q.i] = min(ans[q.i], fixr.query(q.l) + (ll) (q.r-p+1) * H[p]); if (q.r > p) ans[q.i] = min(ans[q.i], fixl.query(q.r) + (ll) (p-q.l+1) * H[p]); } // f(l,p-1) + (i-p+1) * H[p] // f(p+1,i) + (p-l+1) * H[p] ll lv = (p > l ? fixl.query(p-1) : 0); fixl.update(p,r, H[p], lv+(ll)(-p+1)*H[p], (ll)(p-l+1)*H[p]); // f(p+1,r) + (p-i+1) * H[p] // f(i,p-1) + (r-p+1) * H[p] ll rv = (p < r ? fixr.query(p+1) : 0); fixr.update(l,p, -H[p], rv+(ll)(p+1)*H[p], (ll)(r-p+1)*H[p]); } std::vector<long long> minimum_costs(std::vector<int> _H, std::vector<int> L, std::vector<int> R) { H = _H; N = SZ(H); Q = SZ(L); st.init(H); FOR(i,0,Q-1){ int p = st.query(L[i],R[i]); query[p].push_back({L[i],R[i],i}); } ans.assign(Q,0); fixl.build(N); fixr.build(N); solve(0,N-1); return ans; }
#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...