Submission #1321607

#TimeUsernameProblemLanguageResultExecution timeMemory
1321607nagorn_phHorses (IOI15_horses)C++20
100 / 100
732 ms60880 KiB
#include <bits/stdc++.h> #include "horses.h" #define int long long using namespace std; const int mod = 1e9 + 7; const int N = 5e5 + 5; int n; int x[N], y[N]; bool inside[N]; struct segtree { struct node { int val; bool exceed; node() : val(0), exceed(0) {} }; node seg[4 * N]; node create(){ node newnode; newnode.val = 1; newnode.exceed = 0; return newnode; } node merge(node l, node r){ node newnode = create(); newnode.exceed = (l.exceed || r.exceed); newnode.val = (l.val * r.val) % mod; if ((l.val * r.val) >= mod) newnode.exceed = true; return newnode; } void build(int l, int r, int i){ if (l == r) return seg[i].val = x[l], void(); int mid = (l + r) / 2; build(l, mid, 2 * i), build(mid + 1, r, 2 * i + 1); seg[i] = merge(seg[2 * i], seg[2 * i + 1]); } void update(int l, int r, int i, int idx, int val){ if (l == r) return seg[i].val = val, void(); int mid = (l + r) / 2; if (idx <= mid) update(l, mid, 2 * i, idx, val); else update(mid + 1, r, 2 * i + 1, idx, val); seg[i] = merge(seg[2 * i], seg[2 * i + 1]); } node query(int l, int r, int i, int ll, int rr){ if (l >= ll && r <= rr) return seg[i]; if (r < ll || l > rr) return create(); int mid = (l + r) / 2; return merge(query(l, mid, 2 * i, ll, rr), query(mid + 1, r, 2 * i + 1, ll, rr)); } } seg; struct indexmaintain { int seg[4 * N]; void build(int l, int r, int i){ if (l == r) return seg[i] = (x[l] > 1), void(); int mid = (l + r) / 2; build(l, mid, 2 * i), build(mid + 1, r, 2 * i + 1); seg[i] = seg[2 * i] + seg[2 * i + 1]; } void update(int l, int r, int i, int idx, int val){ if (l == r) return seg[i] = (val > 1), void(); int mid = (l + r) / 2; if (idx <= mid) update(l, mid, 2 * i, idx, val); else update(mid + 1, r, 2 * i + 1, idx, val); seg[i] = seg[2 * i] + seg[2 * i + 1]; } int query(int l, int r, int i, int k){ if (l == r) return l; int mid = (l + r) / 2; if (seg[2 * i + 1] >= k) return query(mid + 1, r, 2 * i + 1, k); else return query(l, mid, 2 * i, k - seg[2 * i + 1]); } } indices; struct mxseg{ int seg[4 * N]; void build(int l, int r, int i){ if (l == r) return seg[i] = y[l], void(); int mid = (l + r) / 2; build(l, mid, 2 * i), build(mid + 1, r, 2 * i + 1); seg[i] = max(seg[2 * i], seg[2 * i + 1]); } void update(int l, int r, int i, int idx, int val){ if (l == r) return seg[i] = val, void(); int mid = (l + r) / 2; if (idx <= mid) update(l, mid, 2 * i, idx, val); else update(mid + 1, r, 2 * i + 1, idx, val); seg[i] = max(seg[2 * i], seg[2 * i + 1]); } int query(int l, int r, int i, int ll, int rr){ if (l >= ll && r <= rr) return seg[i]; if (r < ll || l > rr) return 0; int mid = (l + r) / 2; return max(query(l, mid, 2 * i, ll, rr), query(mid + 1, r, 2 * i + 1, ll, rr)); } } mxx; int query(){ int st = 1, exact = indices.seg[1]; for (int i = 1; i <= indices.seg[1]; i++) { int idx = indices.query(1, n, 1, i); // cout << i << ": " << idx << ": " << seg.query(1, n, 1, idx, n).exceed << "\n"; if (seg.query(1, n, 1, idx, n).exceed) { st = idx; exact = i; break; } } if (indices.seg[1] == 0) return mxx.query(1, n, 1, 1, n); long double mx = 0; long double prod = 1.0; int num = 1, prodmod = 1; int fst = indices.query(1, n, 1, exact); if (st < fst) { int val = mxx.query(1, n, 1, st, fst - 1); mx = val; num = val % mod; } for (int i = exact; i >= 1; i--) { int idx = indices.query(1, n, 1, i); prod *= x[idx]; prodmod = (prodmod * x[idx]) % mod; int nxt = (i == 1 ? n + 1 : indices.query(1, n, 1, i - 1)); int mxy = mxx.query(1, n, 1, idx, nxt - 1); if (prod * mxy > mx) { mx = prod * mxy; num = (prodmod * mxy) % mod; } } int answer = ((seg.query(1, n, 1, 1, st - 1).val * num) % mod); return answer; } int32_t init(int32_t N, int32_t X[], int32_t Y[]) { n = N; for (int i = 0; i < n; i++) x[i + 1] = X[i]; for (int i = 0; i < n; i++) y[i + 1] = Y[i]; y[0] = 1; seg.build(1, n, 1); indices.build(1, n, 1); mxx.build(1, n, 1); return query(); } int32_t updateX(int32_t pos, int32_t val) { ++pos; x[pos] = val; seg.update(1, n, 1, pos, val); indices.update(1, n, 1, pos, val); return query(); } int32_t updateY(int32_t pos, int32_t val) { ++pos; y[pos] = val; mxx.update(1, n, 1, pos, val); return query(); } // int32_t main(){ // int32_t n; cin >> n; // int32_t x[n], y[n]; // for (int i = 0; i < n; i++) cin >> x[i]; // for (int i = 0; i < n; i++) cin >> y[i]; // cout << init(n, x, y) << "\n"; // int32_t m; cin >> m; // while (m--) { // int t; cin >> t; // int pos, val; cin >> pos >> val; // if (t == 1) cout << updateX(pos, val) << "\n"; // else cout << updateY(pos, val) << "\n"; // } // }
#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...