Submission #588222

#TimeUsernameProblemLanguageResultExecution timeMemory
588222dnassHorses (IOI15_horses)C++17
100 / 100
1205 ms73604 KiB
#include "horses.h" #include <bits/stdc++.h> using namespace std; typedef long long int lld; typedef long double lf; #define MOD 1000000007LL #define INF 1000000000000000000LL lld n; vector<lld> x, y; set<lld> big; struct itemX{ lld val; itemX(){ val = 0; } itemX(lld valval){ val=valval; val%=MOD; } }; itemX merge(itemX a, itemX b){ lld res = a.val*b.val; res%=MOD; return itemX(res); } itemX build_leaf(lld xxx){ return itemX(xxx); } itemX X_NEUT = itemX(1); struct STX{ vector<itemX> st; void init(){ lld sz = 1; while(sz<n) sz*=2; st.resize(2*sz); } void build(lld v = 1, lld tl = 0, lld tr = n-1){ if(tl==tr) st[v] = build_leaf(x[tl]); else{ lld tm = (tl+tr)/2; build(2*v, tl, tm); build(2*v+1,tm+1,tr); st[v] = merge(st[2*v], st[2*v+1]); } } itemX query(lld l, lld r, lld v = 1, lld tl=0, lld tr=n-1){ if(l>r) return X_NEUT; if(l==tl&&r==tr) return st[v]; lld tm = (tl+tr)/2; return merge(query(l,min(r,tm),2*v, tl, tm),query(max(l, tm+1), r, 2*v+1, tm+1,tr)); } void upd(lld new_val, lld pos, lld v=1,lld tl=0, lld tr=n-1){ if(tl==tr) st[v] = build_leaf(new_val); else{ lld tm = (tl+tr)/2; if(pos<=tm) upd(new_val, pos, 2*v, tl, tm); else upd(new_val, pos, 2*v+1,tm+1,tr); st[v] = merge(st[2*v],st[2*v+1]); } } }; struct itemY{ lld val, ind; itemY(){ val=-INF; ind = -1; } itemY(lld valval, lld indind){ val=valval, ind=indind; } }; itemY merge(itemY a, itemY b){ return a.val>b.val?a:b; } itemY build_leaf(lld xxx, lld indind){ return itemY(xxx,indind); } itemY Y_NEUT = itemY(-INF,-1); struct STY{ vector<itemY> st; void init(){ lld sz = 1; while(sz<n) sz*=2; st.resize(2*sz); } void build(lld v = 1, lld tl = 0, lld tr = n-1){ if(tl==tr) st[v] = build_leaf(y[tl], tl); else{ lld tm = (tl+tr)/2; build(2*v, tl, tm); build(2*v+1,tm+1,tr); st[v] = merge(st[2*v], st[2*v+1]); } } itemY query(lld l, lld r, lld v = 1, lld tl=0, lld tr=n-1){ if(l>r) return Y_NEUT; if(l==tl&&r==tr) return st[v]; lld tm = (tl+tr)/2; return merge(query(l,min(r,tm),2*v, tl, tm),query(max(l, tm+1), r, 2*v+1, tm+1,tr)); } void upd(lld new_val, lld pos, lld v=1,lld tl=0, lld tr=n-1){ if(tl==tr) st[v] = build_leaf(new_val, tl); else{ lld tm = (tl+tr)/2; if(pos<=tm) upd(new_val, pos, 2*v, tl, tm); else upd(new_val, pos, 2*v+1,tm+1,tr); st[v] = merge(st[2*v],st[2*v+1]); } } }; STX segx; STY segy; int calc(){ auto it = big.end(); for(int i=0;i<31;i++){ if(it==big.begin()) break; --it; } auto it2 = it; ++it2; lld next_pos = it2==big.end()?n:(*it2); itemY mxY = segy.query((*it), next_pos-1); lf cur = log((lf)x[(*it)])+log((lf)mxY.val); lf mx = cur; lld mx_pos = mxY.ind; lld prevY = mxY.ind; ++it; while(it!=big.end()){ cur -= log((lf)y[prevY]); it2 = it; ++it2; next_pos = it2==big.end()?n:(*it2); mxY = segy.query((*it), next_pos-1); cur += log((lf)x[(*it)])+log((lf)mxY.val); if(cur>mx){ mx = cur; mx_pos = mxY.ind; } prevY = mxY.ind; ++it; } lld res = segx.query(0, mx_pos).val; res *= y[mx_pos]; res%=MOD; return (int)res; } int init(int N, int X[], int Y[]) { n = (lld) N; x.resize(n); y.resize(n); big.insert(0); for(lld i=0;i<n;i++){ x[i] = (lld)X[i]; y[i] = (lld)Y[i]; if(x[i]>1) big.insert(i); } segx.init(); segx.build(); segy.init(); segy.build(); return calc(); } int updateX(int pos, int val){ segx.upd(val, pos); x[pos] = val; if(val>1){ big.insert(pos); }else if(pos!=0){ auto it = big.find(pos); if(it!=big.end()) big.erase(it); } return calc(); } int updateY(int pos, int val){ segy.upd(val, pos); y[pos] = val; return calc(); }
#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...