제출 #1310047

#제출 시각아이디문제언어결과실행 시간메모리
1310047muhammad-ahmad말 (IOI15_horses)C++20
100 / 100
551 ms45116 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MOD = 1e9 + 7; const int MAXN = 500005; int n; int curX[MAXN], curY[MAXN]; ll treeX[4 * MAXN]; int treeY[4 * MAXN]; set<int> st; // Segment Tree for Product of X (modulo 10^9 + 7) void buildX(int node, int start, int end) { if (start == end) { treeX[node] = curX[start]; return; } int mid = (start + end) / 2; buildX(2 * node, start, mid); buildX(2 * node + 1, mid + 1, end); treeX[node] = (treeX[2 * node] * treeX[2 * node + 1]) % MOD; } void updX(int node, int start, int end, int idx, int val) { if (start == end) { treeX[node] = val; return; } int mid = (start + end) / 2; if (idx <= mid) updX(2 * node, start, mid, idx, val); else updX(2 * node + 1, mid + 1, end, idx, val); treeX[node] = (treeX[2 * node] * treeX[2 * node + 1]) % MOD; } ll queryX(int node, int start, int end, int l, int r) { if (r < start || end < l) return 1; if (l <= start && end <= r) return treeX[node]; int mid = (start + end) / 2; return (queryX(2 * node, start, mid, l, r) * queryX(2 * node + 1, mid + 1, end, l, r)) % MOD; } // Segment Tree for Maximum of Y void buildY(int node, int start, int end) { if (start == end) { treeY[node] = curY[start]; return; } int mid = (start + end) / 2; buildY(2 * node, start, mid); buildY(2 * node + 1, mid + 1, end); treeY[node] = max(treeY[2 * node], treeY[2 * node + 1]); } void updY(int node, int start, int end, int idx, int val) { if (start == end) { treeY[node] = val; return; } int mid = (start + end) / 2; if (idx <= mid) updY(2 * node, start, mid, idx, val); else updY(2 * node + 1, mid + 1, end, idx, val); treeY[node] = max(treeY[2 * node], treeY[2 * node + 1]); } int queryY(int node, int start, int end, int l, int r) { if (r < start || end < l) return 0; if (l <= start && end <= r) return treeY[node]; int mid = (start + end) / 2; return max(queryY(2 * node, start, mid, l, r), queryY(2 * node + 1, mid + 1, end, l, r)); } int solve() { // Collect last ~30 positions where X[i] > 1 vector<int> pos; auto it = st.end(); ll prod = 1; for (int i = 0; i < 35 && it != st.begin(); i++) { it--; pos.push_back(*it); prod *= curX[*it]; if (prod > 2e9) break; // Optimization: past 10^9, previous years can't win } reverse(pos.begin(), pos.end()); // Candidates for best selling year int best_pos_idx = -1; // -1 represents the interval before the first X > 1 int cur_best_y = (pos.empty() ? queryY(1, 0, n - 1, 0, n - 1) : queryY(1, 0, n - 1, 0, pos[0] - 1)); for (int i = 0; i < (int)pos.size(); i++) { int L = pos[i]; int R = (i + 1 < (int)pos.size()) ? pos[i + 1] - 1 : n - 1; int m_i = queryY(1, 0, n - 1, L, R); ll p = 1; int start_search = (best_pos_idx == -1) ? 0 : best_pos_idx + 1; for (int k = start_search; k <= i; k++) { p *= curX[pos[k]]; if (p > 2e9) break; } if (p >= 2e9 || p * m_i >= cur_best_y) { cur_best_y = m_i; best_pos_idx = i; } } ll ans_prod = 1; if (best_pos_idx != -1) ans_prod = queryX(1, 0, n - 1, 0, pos[best_pos_idx]); return (ans_prod * cur_best_y) % MOD; } int init(int N, int X[], int Y[]) { n = N; for (int i = 0; i < n; i++) { curX[i] = X[i]; curY[i] = Y[i]; if (X[i] > 1) st.insert(i); } buildX(1, 0, n - 1); buildY(1, 0, n - 1); return solve(); } int updateX(int pos, int val) { if (curX[pos] > 1) st.erase(pos); curX[pos] = val; if (curX[pos] > 1) st.insert(pos); updX(1, 0, n - 1, pos, val); return solve(); } int updateY(int pos, int val) { curY[pos] = val; updY(1, 0, n - 1, 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...