Submission #1236985

#TimeUsernameProblemLanguageResultExecution timeMemory
123698512baaterHorses (IOI15_horses)C++20
54 / 100
365 ms64036 KiB
#include "horses.h" #include <stack> #include <iostream> #include <vector> #include <algorithm> #include <set> using namespace std; typedef long long ll; const ll MOD = 1E9 + 7; const int MAXN = 500050; int n; vector<int> x(MAXN); vector<int> y(MAXN); set<int> valid_indices; struct ST { int n; vector<ll> seg; ST(int N) : seg(4*N) { int s = 1; for (; s < N; s <<= 1); n = N; } void update(int pos, int val) { pos += n; seg[pos] = val; pos >>= 1; while (pos > 0) { seg[pos] = (seg[pos*2] * seg[pos*2 + 1])%MOD; pos >>= 1; } } ll query(int l, int r) { l += n; r += n; ll ret = 1; while (l < r) { if (l&1) { ret *= seg[l++]; ret %= MOD; } if (r&1) { ret *= seg[--r]; ret %= MOD; } l >>= 1; r >>= 1; } return ret%MOD; } }; struct maxST { ll n; vector<ll> seg; maxST(ll N) : seg(4*N) { int s = 1; for (; s < N; s <<= 1); n = s; } void update(ll pos, ll val) { pos += n; seg[pos] = val; pos >>= 1; while (pos > 0) { seg[pos] = max(seg[pos*2], seg[pos*2 + 1]); pos >>= 1; } } ll query(ll l, ll r) { l += n; r += n; ll ret = 0; while (l < r) { if (l&1) ret = max(ret, seg[l++]); if (r&1) ret = max(ret, seg[--r]); l >>= 1; r >>= 1; } return ret; } }; ST tree(MAXN); maxST maxTree(MAXN); int find_best() { stack<int> to_process; auto it = valid_indices.rbegin(); for (int i = 0; i <= 100; i++) { if (it == valid_indices.rend()) { if (to_process.empty()) { to_process.push(0); break; } else if (to_process.top() != 0) { to_process.push(0); break; } break; } to_process.push(*it); it++; } int bestInd = 0; int current = 0; ll tot = 1; ll currentVal = 0; ll best = 0; current = to_process.top(); to_process.pop(); while (!to_process.empty()) { int next = to_process.top(); to_process.pop(); tot *= x[current]; currentVal = maxTree.query(current, next); if (tot * currentVal >= best) { best = currentVal; bestInd = current; tot = 1; } current = next; } // currentVal = maxTree.query(current, n); // tot *= x[current]; // if (tot * currentVal >= best) { // best = currentVal; // bestInd = current; // } // for (int i = start+1; i < n; i++) { // tot *= x[i]; // if (tot * y[i] >= y[bestInd]) { // bestInd = i; // tot = 1; // } // } return static_cast<int>((tree.query(0, bestInd+1) * best) % MOD); } int solve() { // int num = max(0, n-1001); // int ind = find_best(num); // ll horseNum = tree.query(0, ind+1); // ll cashNum = y[ind]; // cout << horseNum << " " << cashNum << endl; return find_best(); } int init(int N, int X[], int Y[]) { valid_indices.insert(N); n = N; for (int i = 0; i < N; i++) { x[i] = X[i]; y[i] = Y[i]; tree.update(i, x[i]); maxTree.update(i, y[i]); if (x[i] != 1) { valid_indices.insert(i); } } return solve(); } int updateX(int pos, int val) { x[pos] = val; tree.update(pos, val); if (val == 1) { valid_indices.erase(pos); } else { valid_indices.insert(pos); } return solve(); } int updateY(int pos, int val) { maxTree.update(pos, val); y[pos] = val; return solve(); }
#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...