Submission #722699

#TimeUsernameProblemLanguageResultExecution timeMemory
722699Ronin13Holiday (IOI14_holiday)C++17
47 / 100
2504 ms31708 KiB
#include"holiday.h" #include <bits/stdc++.h> #define ll long long #define ull unsigned ll #define pb push_back #define epb emplace_back #define f first #define s second #define pii pair<int,int> #define pll pair<ll,ll> using namespace std; const int dmax = 400001; const int nmax = 200001; struct node{ ll val; ll x; node(){ val = x = 0; return; } }t[4 * nmax]; void upd(int v, int l, int r, int pos, ll val){ if(l > pos || r < pos) return; if(l == r){ t[v].val = val; t[v].x = (val > 0); if(val > 1e9) t[v].x = val; return; } int m = (l + r) / 2; upd(2 * v, l, m, pos, val); upd(2 * v + 1, m + 1, r, pos, val); t[v].val = t[v * 2].val + t[v * 2 + 1].val; t[v].x = t[v * 2].x + t[v * 2 + 1].x; } ll get(int v, int l, int r, int val){ if(l == r){ return 0; } int m = (l + r) /2; if(t[v * 2].x <= val) return t[v * 2].val + get(2 * v + 1, m + 1, r, val - t[v * 2].x); return get(2 * v, l, m, val); } pll ans[dmax][4]; ll a[nmax]; int b[nmax]; //op=0 ---> //op=1 <--- int n; void divide_and_conquer(int l, int r, int optl, int optr, int op, int st, int ind){ int m = (l + r) / 2; if(l > r) return; pll mx = {0, optl}; if(op == 0){ for(int j = optl; j <= optr; j++){ upd(1, 1, n + 1, b[j], a[j]); ll cur = get(1, 1, n + 1, m - j + st); if(cur > mx.f) mx.f = cur, mx.s = j; } ans[m][ind] = mx; for(int j = optl; j <= optr; j++) upd(1, 1, n + 1, b[j], 0); divide_and_conquer(l, m - 1, optl, mx.s, op, st, ind); for(int j = optl; j < mx.s; j++){ upd(1, 1, n + 1, b[j], a[j]); } divide_and_conquer(m + 1, r, mx.s, optr, op, st, ind); for(int j = optl; j <= optr; j++) upd(1, 1, n + 1, b[j], 0); } else { mx.s = optr; for(int j = optr; j >= optl; j--){ upd(1, 1, n + 1, b[j], a[j]); ll cur = get(1, 1, n + 1, m - st + j); if(cur > mx.f) mx.f = cur, mx.s = j; } ans[m][ind] = mx; for(int j = optl; j <= optr; j++) upd(1, 1, n + 1, b[j], 0); divide_and_conquer(l, m - 1, mx.s, optr, op, st, ind); for(int j = optr; j > mx.s; j--){ upd(1, 1, n + 1, b[j], a[j]); } divide_and_conquer(m + 1, r, optl, mx.s, op, st, ind); for(int j = optl; j <= optr; j++) upd(1, 1, n + 1, b[j], 0); } return; } long long findMaxAttraction(int N, int start, int d, int attraction[]) { n = N; pii c[n + 1]; for(int i = 1; i <= N; i++) a[i] = attraction[i - 1]; for(int i = 1; i <= n; i++){ c[i] = {a[i], i}; } upd(1, 1, n + 1, n + 1, 1e9 + 1); sort(c + 1, c + n + 1); reverse(c + 1, c + n + 1); for(int i = 1; i <= n; i++) b[c[i].s] = i; start++; divide_and_conquer(0, d, start, n, 0, start, 0); divide_and_conquer(0, d, 1, start, 1, start, 1); // cout << ans[d][0].f << ' ' << ans[d][1].f << "\n"; if(start == 1){ return ans[d][0].f; } if(start == n) return ans[d][1].f; divide_and_conquer(0, d, start + 1, n, 0, start + 1, 2); divide_and_conquer(0, d, 1, start - 1, 1, start - 1, 3); ll x = max(ans[d][0].f, ans[d][1].f); for(int i = 1; i < d; i++){ ll u = ans[i][0].f; ll pos = ans[i][0].s; ll rem = d - i - (pos - start); rem--; if(rem > 0)x = max(x, u + ans[rem][3].f); u = ans[i][1].f; pos = ans[i][1].s; rem = d - i - (start - pos); rem--; if(rem)x = max(x, u + ans[rem][2].f); } return x; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...