Submission #1251821

#TimeUsernameProblemLanguageResultExecution timeMemory
1251821Zbyszek99Obstacles for a Llama (IOI25_obstacles)C++20
100 / 100
523 ms216312 KiB
#include "obstacles.h" #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #define ll long long #define ld long double #define ull unsigned long long #define ff first #define ss second #define pii pair<int,int> #define pll pair<long long, long long> #define vi vector<int> #define vl vector<long long> #define pb push_back #define rep(i, b) for(int i = 0; i < (b); ++i) #define rep2(i,a,b) for(int i = a; i <= (b); ++i) #define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c) #define count_bits(x) __builtin_popcountll((x)) #define all(x) (x).begin(),(x).end() #define siz(x) (int)(x).size() #define forall(it,x) for(auto& it:(x)) using namespace __gnu_pbds; using namespace std; typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set; //mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());} //ll los(ll a, ll b) {return a + (mt() % (b-a+1));} const int INF = 1e9+50; const ll INF_L = 1e18+40; const ll MOD = 1e9; struct table { pii min_[200001][18]; pii max_[200001][18]; void set(vi v) { rep(i,siz(v)) { min_[i][0] = {v[i],i}; max_[i][0] = {v[i],i}; } rep2(bit,1,17) { rep(i,siz(v)) { min_[i][bit] = min(min_[i][bit-1],(i+(1<<(bit-1)) < siz(v) ? min_[i+(1<<(bit-1))][bit-1] : (pii){1e9,1e9})); max_[i][bit] = max(max_[i][bit-1],(i+(1<<(bit-1)) < siz(v) ? max_[i+(1<<(bit-1))][bit-1] : (pii){-1e9,-1e9})); } } } pii get_max(int l, int r) { int lg = __lg(r-l+1); return max(max_[l][lg],max_[r-(1 << lg)+1][lg]); } pii get_min(int l, int r) { int lg = __lg(r-l+1); return min(min_[l][lg],min_[r-(1 << lg)+1][lg]); } }; struct jump_str { int l,r,v; jump_str operator+(const jump_str& other) { jump_str res; res.l = min(l,other.l); res.r = max(r,other.r); res.v = other.v; return res; } }; table tableX; table tableY; jump_str jump[500001][18]; int vert[200001]; int X[200001]; int Y[200001]; vi pref; int cur_v = 0; int vH[500001]; void split(int l, int r, int h, vector<pii>& ans) { if(l > r) return; int max_col = tableX.get_max(l,r).ss; if(Y[h] > X[max_col]) ans.pb({l,r}); else { split(l,max_col-1,h,ans); split(max_col+1,r,h,ans); } } jump_str get_jump(int l, int r, int h, int prev) { jump_str j = {(int)1e9,(int)-1e9,prev}; int pop_H = vH[prev]; int l2 = l; int r2 = r; while(l2 <= r2) { int mid = (l2+r2)/2; if(tableX.get_min(mid,r).ff < tableY.get_min(h,pop_H).ff) { j.l = mid; l2 = mid+1; } else { r2 = mid-1; } } l2 = l; r2 = r; while(l2 <= r2) { int mid = (l2+r2)/2; if(tableX.get_min(l,mid).ff < tableY.get_min(h,pop_H).ff) { j.r = mid; r2 = mid-1; } else { l2 = mid+1; } } return j; } void rek(int l, int r, int pref_max, int pop) { int v = cur_v++; vH[v] = pref[pref_max]; if(pop != -1) jump[v][0] = get_jump(l,r,pref[pref_max],pop); else jump[v][0] = {(int)1e9,(int)-1e9,v}; int max_col = tableX.get_max(l,r).ss; int l2 = 0; int r2 = pref_max; int down_ok = pref_max; while(l2 <= r2) { int mid = (l2+r2)/2; if(Y[pref[mid]] > X[max_col]) { down_ok = mid; r2 = mid-1; } else { l2 = mid+1; } } vector<pii> segs; if(down_ok != 0) split(l,r,pref[down_ok-1],segs); else segs.pb({l,r}); int v_down = cur_v++; vH[v_down] = pref[down_ok]; if(down_ok != pref_max) { if(tableY.get_min(pref[down_ok],pref[pref_max]).ff <= tableX.get_min(l,r).ff) { jump[v_down][0] = {(int)1e9,(int)-1e9,v_down}; } else { jump[v_down][0] = get_jump(l,r,pref[down_ok],v); } } else { jump[v_down][0] = {(int)1e9,(int)-1e9,v}; } if(down_ok == 0) { rep2(i,l,r) { vert[i] = v_down; } return; } forall(it,segs) { if(tableY.get_min(pref[down_ok-1],pref[down_ok]).ff > tableX.get_min(it.ff,it.ss).ff) { rek(it.ff,it.ss,down_ok-1,v_down); } else { rek(it.ff,it.ss,down_ok-1,-1); } } } void initialize(vi T, vi H) { rep(i,siz(T)) Y[i] = T[i]; rep(i,siz(H)) X[i] = H[i]; tableY.set(T); tableX.set(H); int pop = -1; rep(i,siz(T)) { if(Y[i] >= pop) { pref.pb(i); pop = Y[i]; } } vH[0] = pref.back(); rek(0,siz(H)-1,siz(pref)-1,-1); rep2(bit,1,17) { rep(i,cur_v) { jump[i][bit] = jump[i][bit-1] + jump[jump[i][bit-1].v][bit-1]; } } } bool can_reach(int L, int R, int S, int D) { if(S > D) swap(D,S); int v1 = vert[S]; int v2 = vert[D]; for(int bit = 17; bit >= 0; bit--) { if(jump[v1][bit].l >= L) { v1 = jump[v1][bit].v; } if(jump[v2][bit].r <= R) { v2 = jump[v2][bit].v; } } int row = min(vH[v1],vH[v2]); return tableX.get_max(S,D).ff < Y[row]; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...