제출 #1247264

#제출 시각아이디문제언어결과실행 시간메모리
1247264SpyrosAliv말 (IOI15_horses)C++20
37 / 100
387 ms95396 KiB
#include "horses.h" #include <bits/stdc++.h> using namespace std; #define ll long long const ll MOD = 1e9+7; const ll MAXV = 1e9; const int MN = 5e5+5; int n; vector<int> x, y; set<int> diff; class SegTree { private: vector<ll> seg; ll query(int node, int start, int end, int l, int r) { if (start > r || end < l) return 1LL; else if (start >= l && end <= r) return seg[node]; else { int mid = (start + end) / 2; return query(node*2+1, start, mid, l, r) * query(node*2+2, mid+1, end, l, r) % MOD; } } void update(int node, int start, int end, int idx, int v) { if (start == end) { seg[node] = v; } else { int mid = (start + end) / 2; if (idx <= mid) update(node*2+1, start, mid, idx, v); else update(node*2+2, mid+1, end, idx, v); seg[node] = seg[node*2+1] * seg[node*2+2] % MOD; } } public: void init(int nn) { seg.resize((nn + 1) * 8); } void upd(int idx, int v) { update(0, 0, n-1, idx, v); } ll query(int l, int r) { if (l > r) return 0; return query(0, 0, n-1, l, r); } }; SegTree seg; class SegTreeMax { private: struct Node { int maxv, idx; }; vector<Node> seg; Node merge(Node a, Node b) { Node c = a; if (b.maxv > c.maxv) { c = b; } return c; } Node query(int node, int start, int end, int l, int r) { if (start > r || end < l) return {-1, -1}; else if (start >= l && end <= r) return seg[node]; else { int mid = (start + end) / 2; return merge(query(node*2+1, start, mid, l, r), query(node*2+2, mid+1, end, l, r)); } } void update(int node, int start, int end, int idx, int v) { if (start == end) { seg[node] = {v, idx}; } else { int mid = (start + end) / 2; if (idx <= mid) update(node*2+1, start, mid, idx, v); else update(node*2+2, mid+1, end, idx, v); seg[node] = merge(seg[node*2+1], seg[node*2+2]); } } public: void init(int nn) { seg.resize((nn + 1) * 8); } void upd(int idx, int v) { update(0, 0, n-1, idx, v); } int query(int l, int r) { if (l > r) return 0; return query(0, 0, n-1, l, r).idx; } }; SegTreeMax maxSeg; int get_ans() { vector<int> arr; for (int i = n-1; arr.size() < 32 && i >= 0; i--) { if (x[i] != 1) { arr.push_back(i); continue; } auto pp = diff.lower_bound(i); pp--; int prev = *pp + 1; arr.push_back(maxSeg.query(prev, i)); i = prev; } reverse(arr.begin(), arr.end()); int sz = arr.size(); //for (int i = 0; i < sz; i++) { // cout << arr[i] << " "; //} cout << "\n"; ll dp = y[arr[sz-1]]; int idx = arr[sz-1]; for (int i = sz-2; i >= 0; i--) { ll dp2 = max((ll)y[arr[i]], (ll)x[arr[i + 1]] * dp); if (dp2 > MAXV) break; dp = dp2; idx = arr[i]; } ll b4 = seg.query(0, idx); return (b4 * dp) % MOD; } int init(int N, int X[], int Y[]) { n = N; seg.init(n); maxSeg.init(n); diff.insert(-1); diff.insert(n+1); for (int i = 0; i < n; i++) { x.push_back(X[i]); y.push_back(Y[i]); seg.upd(i, X[i]); if (x[i] != 1) diff.insert(i); maxSeg.upd(i, y[i]); } return get_ans(); } int updateX(int pos, int val) { if (x[pos] != 1) diff.erase(pos); x[pos] = val; if (x[pos] != 1) diff.insert(pos); seg.upd(pos, x[pos]); return get_ans(); } int updateY(int pos, int val) { y[pos] = val; maxSeg.upd(pos, val); return get_ans(); }
#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...