제출 #885914

#제출 시각아이디문제언어결과실행 시간메모리
885914Zanite휴가 (IOI14_holiday)C++17
24 / 100
589 ms45816 KiB
// When we're in drama, // there's that person over there // polishing their skill. // 抗えぬ運命と決まっているのなら // 私はあなたの為に生きたい // 誰かの為に生きてこその人生 // 輝を増すこと知っているから // Zanite's template #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> // Pragmas // #pragma GCC optimize("Ofast") // #pragma GCC optimize("unroll-loops") // #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") // Namespaces using namespace std; using namespace __gnu_pbds; // Data types using si = short int; using ll = long long; using ull = unsigned long long; using lll = __int128; using ld = long double; // Pairs using pii = pair<int, int>; using psi = pair<si, si>; using pll = pair<ll, ll>; using plll = pair<lll, lll>; using pld = pair<ld, ld>; #define fi first #define se second // PBDS template<typename Z> using ordered_set = tree<Z, null_type, less<Z>, rb_tree_tag, tree_order_statistics_node_update>; // Quick macro functions #define sqr(x) ((x)*(x)) #define debug(x) cout << #x << " = " << (x) << '\n' #define debugV(v, x) cout << #v << "[" << (x) << "] = " << (v[x]) << '\n' #define rrebug(x) cerr << #x << " = " << (x) << '\n' #define rrebugV(v, x) cerr << #v << "[" << (x) << "] = " << (v[x]) << '\n' #define All(x) x.begin(), x.end() #define Sort(x) sort(All(x)) #define Reverse(x) reverse(All(x)) #define Uniqueify(x) Sort(x); x.erase(unique(All(x)), x.end()) #define RandomSeed chrono::steady_clock::now().time_since_epoch().count() #define MultipleTestcases int _tc; cin >> _tc; for (int _cur_tc = 1; _cur_tc <= _tc; _cur_tc++) // Check min and max template<typename Z> bool chmin(Z &a, Z b) {return (b < a) ? a = b, true : false;} template<typename Z> bool chmax(Z &a, Z b) {return (b > a) ? a = b, true : false;} // Other constants const ll INF = 1e18; const ll iINF = 1e9; const ld EPS = 1e-9; const ld iEPS = 1e-6; pll operator+(const pll &a, const pll &b) { return make_pair(a.fi + b.fi, a.se + b.se); } pll operator-(const pll &a, const pll &b) { return make_pair(a.fi - b.fi, a.se - b.se); } const ull LARGE = 1'000'000'000'000'001; // 1e15 + 1 ull cnt(ull x) {return x / LARGE;} ull val(ull x) {return x % LARGE;} class PersistentSegtree { private: int n, ptr, sz; struct P { ull val = 0; int l, r; }; vector<P> node; vector<int> root; int newNode() { node.emplace_back(); return ptr++; } int copyNode(int idx) { node.push_back(node[idx]); return ptr++; } int build(int l, int r) { int idx = newNode(); if(l == r) return idx; node[idx].l = build(l, (l + r) / 2); node[idx].r = build((l + r) / 2 + 1, r); return idx; } int update(int idx, int l, int r, int x, ull val) { idx = copyNode(idx); if(l == r) { node[idx].val += val; return idx; } int mid = (l + r) / 2; if(x <= mid) node[idx].l = update(node[idx].l, l, mid, x, val); else node[idx].r = update(node[idx].r, mid + 1, r, x, val); node[idx].val = node[node[idx].l].val + node[node[idx].r].val; return idx; } ull query(int idxl, int idxr, int l, int r, int x, int y) { if(y < l || r < x) return 0; if(x <= l && r <= y) return node[idxr].val - node[idxl].val; int mid = (l + r) / 2; return query(node[idxl].l, node[idxr].l, l, mid, x, y) + query(node[idxl].r, node[idxr].r, mid + 1, r, x, y); } ull search(int idx, int l, int r, ull x) { if (cnt(node[idx].val) <= x) return val(node[idx].val); if (l == r) return 0; int mid = (l + r) / 2; if (cnt(node[node[idx].l].val) >= x) { return search(node[idx].l, l, mid, x); } else { return val(node[node[idx].l].val) + search(node[idx].r, mid + 1, r, x - cnt(node[node[idx].l].val)); } } public: PersistentSegtree(int _n) : n(_n), ptr(0) { sz = 30 * n; node.reserve(sz); root.push_back(build(1, n)); } void update(int x, ull val) { root.push_back(update(root.back(), 1, n, x, val)); } ull query(int l, int r, int x, int y) { return query(root[l - 1], root[r], 1, n, x, y); } ull search(int i, int x) { return search(root[i], 1, n, x); } }; const int maxN = 100'023; int N, start, D; ll A[maxN]; vector<ll> getOpt(vector<ll> &P, int mult) { int K = P.size(); vector<pll> compress; for (int i = 0; i < K; i++) { compress.push_back({P[i], i}); } sort(All(compress), greater<pll>()); vector<int> idx(K); for (int i = 0; i < K; i++) { idx[compress[i].se] = i + 1; } // Compute "convex hull" PersistentSegtree PS(K); for (int i = 0; i < K; i++) { PS.update(idx[i], (ull)P[i] + LARGE); } auto get = [&](int consider, int t) { int tk = t - mult * (consider + 1); if (tk <= 0) { return 0ll; } ll ans = PS.search(consider + 1, tk); // cout << "get " << consider << " " << t << ": " << ans << "\n"; // cout << "search(" << consider << ", " << tk << ") = " << ans << "\n"; return ans; }; auto get_isect = [&](int i, int j) { int l = j, r = 3*K, ans = -1; while (l <= r) { int m = (l + r) / 2; if (get(j, m) > get(i, m)) { ans = m; r = m - 1; } else { l = m + 1; } } return ans; }; vector<int> CH = {0}; vector<int> isect; for (int i = 1; i < K; i++) { int cur_isect = get_isect(CH.back(), i); if (cur_isect == -1) continue; bool push = true; while (CH.size() >= 2) { cur_isect = get_isect(CH.back(), i); if (cur_isect == -1) { push = false; break; } if (cur_isect <= isect.back()) { CH.pop_back(); isect.pop_back(); } else break; } if (push) { isect.push_back(get_isect(CH.back(), i)); CH.push_back(i); } } // debug(CH); // debug(isect); int cs = CH.size(); vector<ll> ret; for (int i = 0, ptr = 0; i <= 3*K; i++) { while ((ptr < cs-1) && (i >= isect[ptr])) ptr++; ret.push_back(get(CH[ptr], i)); } // debug(ret); // cout << "===\n"; return ret; } ll findMaxAttraction(int N, int start, int D, int attraction[]) { for (int i = 1; i <= N; i++) A[i] = attraction[i-1]; D = min(D, 3*N); start++; vector<ll> L, R; for (int i = start-1; i >= 0; i--) L.push_back(A[i]); for (int i = start+1; i <= N+1; i++) R.push_back(A[i]); // debug(L); debug(R); ll ans = 0; for (int tl = 1; tl <= 2; tl++) { int tr = 3 - tl; vector<ll> optL = getOpt(L, tl); vector<ll> optR = getOpt(R, tr); while ((int)optL.size() <= D) optL.push_back(optL.back()); while ((int)optR.size() <= D) optR.push_back(optR.back()); // debug(optL); debug(optR); // don't visit attraction at start for (int i = 0; i <= D; i++) { chmax(ans, optL[i] + optR[D - i]); } // visit attraction at start for (int i = 0; i <= D-1; i++) { chmax(ans, optL[i] + optR[D-1 - i] + A[start]); } } return ans; } // あなたの傍に居させて... // dibisakan
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...