제출 #1289695

#제출 시각아이디문제언어결과실행 시간메모리
1289695Minbaev말 (IOI15_horses)C++20
100 / 100
765 ms31928 KiB
//#include "grader.cpp" #include "horses.h" #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #pragma GCC target("avx,avx2,fma") #pragma GCC optimize("Ofast,unroll-loops") using namespace std; using namespace __gnu_pbds; #define pb push_back #define all(x) x.begin(),x.end() #define ar array #define mrand(a, b) uniform_int_distribution<int>(a, b)(rng) template<class T>bool umax(T &a,T b){if(a<b){a=b;return true;}return false;} template<class T>bool umin(T &a,T b){if(b<a){a=b;return true;}return false;} template<class T> using ste = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>; mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); const long long inf = 1e17 + 7; const int mod = 1e9 + 7; const int N = 5e5 + 5; const int md = 998244353; int binpow(int a, int b, int m){ if(b == 0)return 1; if(b % 2 == 0){ int c = binpow(a,b/2,m); return (c*c)%m; } return (binpow(a,b-1,m)*a)%m; } int divi(int a, int b, int m){ return (a*(binpow(b,m-2, m)))%m; } vector<int>a(N), b(N); int n; long long t[N*4]; int mxi[N*4], cnt[N*4]; void update(int tl, int tr, int v, int pos, int val){ if(tl == tr){ t[v] = val; return; } int tm = (tl + tr) / 2; if(pos <= tm) update(tl, tm, v*2, pos, val); else update(tm+1, tr, v*2+1, pos, val); t[v] = (t[v*2] * t[v*2+1]) % mod; } long long get(int tl, int tr, int v, int l, int r){ if(r < tl || tr < l || r < l)return 1ll; if(l <= tl && tr <= r){ return t[v]; } int tm = (tl + tr) / 2; return (get(tl, tm, v*2, l, r) * get(tm+1, tr, v*2+1, l, r)) % mod; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- void update2(int tl, int tr, int v, int pos, int val){ if(tl == tr){ mxi[v] = val; return; } int tm = (tl + tr) / 2; if(pos <= tm) update2(tl, tm, v*2, pos, val); else update2(tm+1, tr, v*2+1, pos, val); mxi[v] = max(mxi[v*2], mxi[v*2+1]); } int get2(int tl, int tr, int v, int l, int r){ if(r < tl || tr < l || r < l)return 0; if(l <= tl && tr <= r){ return mxi[v]; } int tm = (tl + tr) / 2; return max(get2(tl, tm, v*2, l, r), get2(tm+1, tr, v*2+1, l, r)); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- void upd_cnt(int tl, int tr, int v, int pos, int val){ if(tl == tr){ cnt[v] = val; return; } int tm = (tl + tr) / 2; if(pos <= tm) upd_cnt(tl, tm, v*2, pos, val); else upd_cnt(tm+1, tr, v*2+1, pos, val); cnt[v] = cnt[v*2] + cnt[v*2+1]; } int get_cnt(int tl, int tr, int v, int l, int r){ if(r < tl || tr < l || r < l)return 0; if(l <= tl && tr <= r){ return cnt[v]; } int tm = (tl + tr) / 2; return (get_cnt(tl, tm, v*2, l, r) + get_cnt(tm+1, tr, v*2+1, l, r)); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- vector<int>rb(N), vla(N), lb(N, -1); long long fi(int ind, int val){ long long sum = get(0, n, 1, 0, ind); long long u = (sum * val) % mod; return u; } int init(int N, int X[], int Y[]){ n = N; for(int i = 0;i<n;i++){ b[i] = Y[i]; a[i] = X[i]; update(0, n, 1, i, a[i]); update2(0, n, 1, i, b[i]); if(a[i] > 1) upd_cnt(0, n, 1, i, 1); else upd_cnt(0, n, 1, i, 0); } for(int i = 0;i<n;i++){ if(i == 0){ lb[i] = i; rb[i] = i; continue; } if(a[i] == 1){ lb[i] = lb[i-1]; rb[i] = i; rb[lb[i]] = i; } if(a[i] > 1){ lb[i] = i; rb[i] = i; } } for(int i = 0;i<n;i++){ vla[i] = get2(0, n, 1, i, rb[i]); } int l = 0, r = n-1, ans = 0; while(l <= r){ int mid = (l + r) / 2; if(get_cnt(0, n, 1, mid, n) >= 32){ ans = mid; l = mid + 1; } else r = mid - 1; } long long mx = -1, sum = 1, val = -1; for(int i = ans;i<n;){ int iop = rb[i]; int x = X[i]; int y = vla[i]; if(mx == -1){ mx = i; sum = 1; val = y; } else{ sum *= x; if(val / y < sum){ mx = i; sum = 1; val = y; } } i = iop + 1; } /*cout << "\n"; for(int i = 0;i<n;i++)cout << vla[i] << " "; cout << "\n"; for(int i = 0;i<n;i++)cout << rb[i] << " "; cout << "\n\n"; */ return fi(mx, val); } int updateX(int pos, int vl){ update(0, n, 1, pos, vl); if(a[pos] != vl){ if(vl == 1){ int l2 = 0, r2 = pos-1, ans2 = 0; while(l2 <= r2){ int mid = (l2 + r2) / 2; if(get_cnt(0, n, 1, mid, pos-1) == 0){ r2 = mid - 1; } else { ans2 = mid; l2 = mid + 1; } } int yu = rb[pos]; rb[pos] = pos; rb[ans2] = yu; vla[pos] = b[pos]; vla[ans2] = get2(0, n, 1, ans2, rb[ans2]); } else if(a[pos] == 1){ int l2 = 0, r2 = pos-1, ans2 = 0; while(l2 <= r2){ int mid = (l2 + r2) / 2; if(get_cnt(0, n, 1, mid, pos - 1) == 0){ r2 = mid - 1; } else { ans2 = mid; l2 = mid + 1; } } rb[pos] = rb[ans2]; if(ans2 != pos)rb[ans2] = pos - 1; vla[pos] = get2(0, n, 1, pos, rb[pos]); vla[ans2] = get2(0, n, 1, ans2, rb[ans2]); } } a[pos] = vl; // cout << "\n"; // for(int i = 0;i<n;i++)cout << vla[i] << " "; // cout << "\n"; // for(int i = 0;i<n;i++)cout << rb[i] << " "; // cout << "\n\n"; if(vl == 1) upd_cnt(0, n, 1, pos, 0); else upd_cnt(0, n, 1, pos, 1); int l = 0, r = n-1, ans = 0; while(l <= r){ int mid = (l + r) / 2; if(get_cnt(0, n, 1, mid, n) >= 32){ ans = mid; l = mid + 1; } else r = mid - 1; } long long mx = -1, sum = 1, val = -1; for(int i = ans;i<n;){ int iop = rb[i]; int x = a[i]; int y = vla[i]; if(mx == -1){ mx = i; sum = 1; val = y; } else{ sum *= x; if(val / y < sum){ mx = i; sum = 1; val = y; } } i = iop + 1; } return fi(mx, val); } int updateY(int pos, int vl){ b[pos] = vl; update2(0, n, 1, pos, vl); int l2 = 0, r2 = pos, ans2 = 0; while(l2 <= r2){ int mid = (l2 + r2) / 2; if(get_cnt(0, n, 1, mid, pos) == 0){ r2 = mid - 1; } else { ans2 = mid; l2 = mid + 1; } } // cout << ans2 << "\n"; vla[ans2] = get2(0, n, 1, ans2, rb[ans2]); if(ans2 != pos)vla[pos] = vl; // for(int i = 0;i<n;i++){ // cout << vla[i] << ' '; // } // cout << "\n"; int l = 0, r = n-1, ans = 0; while(l <= r){ int mid = (l + r) / 2; if(get_cnt(0, n, 1, mid, n) >= 32){ ans = mid; l = mid + 1; } else r = mid - 1; } long long mx = -1, sum = 1, val = -1; for(int i = ans;i<n;){ int iop = rb[i]; int x = a[i]; int y = vla[i]; if(mx == -1){ mx = i; sum = 1; val = y; } else{ sum *= x; if(val / y < sum){ mx = i; sum = 1; val = y; } } i = iop + 1; } return fi(mx, val); } /* 7 0 2 1 6 2 1 7 2 1 12 2 1 14 2 1 18 2 1 21 2 1 10 1 2 3 4 5 6 7 8 9 10 */ /*signed main() { // freopen("seq.in", "r", stdin); // freopen("seq.out", "w", stdout); ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL); int tt=1;// cin >> tt; while(tt--)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...