Submission #740049

#TimeUsernameProblemLanguageResultExecution timeMemory
740049fractlpacaHorses (IOI15_horses)C++17
77 / 100
1539 ms64908 KiB
#include "horses.h" #include <vector> #include <algorithm> #include <set> // #include <iostream> #define v vector #define ll long long #define fi first #define se second #define MOD ((ll) 1000000007) #define INF ((ll) 1000000001) using namespace std; int *x; int *y; int n; // Editorial Subtask 5 v<ll> xs_mod; // v<ll> xs_trunc; v<int> ys_max; set<pair<int, int>> ranges; ll query_xs_mod(int L, int R, int l, int r, int index) { if (r<L || l>R) return 1; if (l>=L and r<=R) return xs_mod[index]; int mid = (l+r)/2; ll subl = query_xs_mod(L, R, l, mid, index*2); ll subr = query_xs_mod(L, R, mid+1, r, index*2+1); return (subl*subr)%MOD; } void update_xs_mod(int pos, int value, int l, int r, int index) { int mid = (l+r)/2; if (l==r){ xs_mod[index] = value; return; } if (pos <= mid){ update_xs_mod(pos, value, l, mid, index*2); } else { update_xs_mod(pos, value, mid+1, r, index*2+1); } xs_mod[index] = (xs_mod[index*2]*xs_mod[index*2+1])%MOD; } int query_ys_max(int L, int R, int l, int r, int index) { if (r<L || l>R) return -1; if (l>=L and r<=R) return ys_max[index]; int mid = (l+r)/2; int subl = query_ys_max(L, R, l, mid, index*2); int subr = query_ys_max(L, R, mid+1, r, index*2+1); if (subl == -1) return subr; if (subr == -1) return subl; if (y[subl] > y[subr]) return subl; return subr; } void update_ys_max(int pos, int value, int l, int r, int index) { if (l==r) { y[pos] = value; ys_max[index] = pos; return; } int mid = (l+r)/2; if (pos <= mid){ update_ys_max(pos, value, l, mid, index*2); } else { update_ys_max(pos, value, mid+1, r, index*2+1); } int subl = ys_max[index*2]; int subr = ys_max[index*2+1]; int ans = 0; if (subl == -1) ans = subr; else if (subr == -1) ans = subl; else if (y[subl] > y[subr]) ans = subl; else ans = subr; ys_max[index] = ans; } int solve() { // cerr<<"Ranges: "; // for(auto it=ranges.begin(); it!=ranges.end(); it++) { // cerr<<"("<<it->fi<<", "<<it->se<<"), "; // } cerr<<endl; auto it = ranges.end(); it--; int max_i = query_ys_max(it->fi, it->se, 0, n-1, 1); ll pop = x[max_i]; it--; for(int counter=0; counter<60; counter++) { int i = query_ys_max(it->fi, it->se, 0, n-1, 1); if (y[i] > y[max_i]*pop) { max_i = i; pop=1; } pop = min(pop*x[i], INF); if (it==ranges.begin()) break; it--; } ll mult = query_xs_mod(0, max_i, 0, n-1, 1); return (int) ((mult*y[max_i])%MOD); } int init(int N, int X[], int Y[]) { n = N; x = X; y = Y; xs_mod = v<ll> (4*n, 1); //xs_trunc = v<ll> (4*n, 1); ys_max = v<int> (4*n, 1); for (int i=0; i<n; i++) { update_xs_mod(i, X[i], 0, n-1, 1); //update_xs_trunc(i, X[i], 0, n-1, 1); update_ys_max(i, Y[i], 0, n-1, 1); ranges.insert({i, i}); } for(auto it = ranges.begin(); it!=ranges.end(); it++) { if (x[it->fi] == 1 && it!=ranges.begin()) { auto prev = it; prev--; if (x[prev->fi] == 1) { int new_start = prev->fi, new_end=it->se; ranges.erase(prev); ranges.erase(it); ranges.insert({new_start, new_end}); } } } return solve(); } int updateX(int pos, int val) { if (val == 1 && x[pos] != 1){ auto it = ranges.find({pos, pos}); int new_start = pos, new_end = pos; if (it!=ranges.begin()) { auto prev = it; prev--; if (x[prev->fi] == 1) { new_start = prev->fi; ranges.erase(prev); } } auto next = it; next++; if (next!=ranges.end()) { if (x[next->fi] == 1) { new_end = next->se; ranges.erase(next); } } ranges.erase(it); ranges.insert({new_start, new_end}); } else if (val!=1 && x[pos] == 1) { auto it = ranges.upper_bound({pos, n}); it--; int start = it->fi, end = it->se; if (pos > start) ranges.insert({start, pos-1}); if (pos < end) ranges.insert({pos+1, end}); ranges.erase(it); ranges.insert({pos, pos}); } x[pos] = val; update_xs_mod(pos, val, 0, n-1, 1); //update_xs_trunc(pos, val, 0, n-1, 1); return solve(); } int updateY(int pos, int val) { update_ys_max(pos, val, 0, n-1, 1); 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...