(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 #82831

#TimeUsernameProblemLanguageResultExecution timeMemory
82831BenqMeetings (IOI18_meetings)C++14
100 / 100
2763 ms324788 KiB
#pragma GCC optimize ("O3") #pragma GCC target ("sse4") #include <bits/stdc++.h> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> #include <ext/rope> using namespace std; using namespace __gnu_pbds; using namespace __gnu_cxx; typedef long long ll; typedef long double ld; typedef complex<ld> cd; typedef pair<int, int> pi; typedef pair<ll,ll> pl; typedef pair<ld,ld> pd; typedef vector<int> vi; typedef vector<ld> vd; typedef vector<ll> vl; typedef vector<pi> vpi; typedef vector<pl> vpl; typedef vector<cd> vcd; template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; #define FOR(i, a, b) for (int i=a; i<(b); i++) #define F0R(i, a) for (int i=0; i<(a); i++) #define FORd(i,a,b) for (int i = (b)-1; i >= a; i--) #define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--) #define sz(x) (int)(x).size() #define mp make_pair #define pb push_back #define f first #define s second #define lb lower_bound #define ub upper_bound #define all(x) x.begin(), x.end() const int MOD = 1000000007; const ll INF = 1e18; const int MX = 1<<20; const int SZ = 750001; #include "meetings.h" pl operator*(const pl& l, const ll& r) { return {l.f*r,l.s*r}; } pl operator+(const pl& l, const pl& r) { return {l.f+r.f,l.s+r.s}; } pl operator+=(pl& l, const pl& r) { return l = {l.f+r.f,l.s+r.s}; } int N; vpi hei; void checkmn(ll& x, ll y) { x = min(x,y); } struct RMQ { int mx[SZ][21]; int bet(int a, int b) { return hei[a] > hei[b] ? a : b; } RMQ() { F0R(i,N) mx[i][0] = i; FOR(j,1,21) F0R(i,N-(1<<j)+1) mx[i][j] = bet(mx[i][j-1],mx[i+(1<<(j-1))][j-1]); } int query(int L, int R) { int x = 31-__builtin_clz(R-L+1); return bet(mx[L][x],mx[R-(1<<x)+1][x]); } }; RMQ RM; ll ans[SZ]; vector<array<int,3>> tmp[SZ]; struct line { int s,e; ll m,b; line() {} line(int _s, int _e, ll _m, ll _b) { s = _s, e = _e, m = _m, b = _b; } ll eval(int x) { return m*x+b; } }; line d[SZ]; struct lineContain { int s,e; ll lazy = 0; lineContain(int _s, int _e) { s = _s, e = _e; } ll evalBack() { if (!size()) return 0; return d[e].eval(d[e].e)+lazy; } line front() { line l = d[s]; l.b += lazy; return l; } line back() { line l = d[e]; l.b += lazy; return l; } line pop_front() { line l = front(); s ++; return l; } line pop_back() { line l = back(); e --; return l; } ll get(int m) { if (size() == 0 || m < d[s].s) return 0; int lo = s, hi = e; while (lo < hi) { int mid = (lo+hi+1)/2; if (d[mid].s <= m) lo = mid; else hi = mid-1; } return d[lo].eval(m)+lazy; } ll evalFront(ll x) { return d[s].eval(x)+lazy; } void push_back(line l) { l.b -= lazy; d[++e] = l; } void push_front(line l) { l.b -= lazy; d[--s] = l; } int size() { return e-s+1; } }; lineContain divi(int lo, int hi) { if (lo > hi) return lineContain(lo,lo-1); ll x = RM.query(lo,hi); auto l = divi(lo,x-1); auto r = divi(x+1,hi); for (auto y: tmp[x]) checkmn(ans[y[2]],(ll)(x-y[0]+1)*hei[x].f+r.get(y[1])); r.lazy += (x-lo+1)*hei[x].f; int right = x; ll lst = l.evalBack(); while (sz(r)) { ll e = r.front().e; ll a = lst+(e-x+1)*hei[x].f; ll b = r.evalFront(e); if (a <= b) { right = e; r.pop_front(); continue; } else { ll s = r.front().s; while (s < e) { ll m = (s+e)/2; a = lst+(m-x+1)*hei[x].f; b = r.evalFront(m); if (a <= b) s = m+1; else e = m; } right = s-1; auto a = r.pop_front(); a.s = s; r.push_front(a); break; // binary search } } l.pb(line(x,right,hei[x].f,lst-hei[x].f*(x-1))); if (sz(l) > sz(r)) { while (sz(r)) l.pb(r.pop_front()); return l; } else { while (sz(l)) r.push_front(l.pop_back()); return r; } } void solve(vi L, vi R) { RM = RMQ(); vi h; F0R(i,N) h.pb(i); sort(all(h),[](int a, int b) { return hei[a] < hei[b]; }); F0R(i,SZ) tmp[i].clear(); F0R(i,sz(L)) tmp[RM.query(L[i],R[i])].pb({L[i],R[i],i}); divi(0,N-1); } std::vector<long long> minimum_costs(std::vector<int> H, std::vector<int> L, std::vector<int> R) { N = sz(H); F0R(i,N) hei.pb({H[i],i}); F0R(i,sz(L)) ans[i] = INF; solve(L,R); reverse(all(hei)); F0R(i,sz(L)) { L[i] = sz(H)-1-L[i]; R[i] = sz(H)-1-R[i]; swap(L[i],R[i]); } // cout << "\n"; solve(L,R); vl ret; F0R(i,sz(L)) ret.pb(ans[i]); return ret; } /* int main() { int N,Q; cin >> N >> Q;// N = Q = 750000; vi H(N), L(Q), R(Q); F0R(i,N) { // H[i] = rand() % 1000000000; cin >> H[i]; } F0R(i,Q) { L[i] = rand() % N, R[i] = rand() % N; if (L[i] > R[i]) swap(L[i],R[i]); cin >> L[i] >> R[i]; } vl C = minimum_costs(H, L, R); for (auto a: C) cout << a << " "; }*/
#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...