Submission #1251698

#TimeUsernameProblemLanguageResultExecution timeMemory
1251698Zbyszek99Obstacles for a Llama (IOI25_obstacles)C++20
23 / 100
2101 ms137988 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]); } }; table tableX; table tableY; pii max_H[200001]; int X[200001]; int Y[200001]; void rek(int l, int r, int Hr, pii pop) { // cerr << l << " " << r << " " << Hr << " " << pop.ff << " " << pop.ss << " rek\n"; if(l > r) return; int max_row = tableY.get_max(0,Hr).ss; int max_col = tableX.get_max(l,r).ss; if(Y[max_row] <= X[max_col]) { rek(l,max_col-1,Hr,pop); rek(max_col+1,r,Hr,pop); return; } int min_col = tableX.get_min(l,r).ss; int min_row = tableY.get_min(max_row,Hr+1).ss; if(X[min_col] >= Y[min_row]) { pop = {max_row,l}; } // cerr << pop.ff << " " << pop.ss << " " << max_row << " " << min_row << " " << max_col << " " << min_col << " pop\n"; if(max_row == 0) { // cerr << l << " " << r << " xd\n"; rep2(i,l,r) max_H[i] = pop; } else { rek(l,r,max_row-1,pop); } } void initialize(vi T, vi H) { T.pb(-1); rep(i,siz(T)) Y[i] = T[i]; rep(i,siz(H)) X[i] = H[i]; tableY.set(T); tableX.set(H); rek(0,siz(H)-1,siz(T)-2,{siz(T)-1,0}); } bool can_reach(int L, int R, int S, int D) { int row = min(max_H[S].ff,max_H[D].ff); int l = max_H[S].ss; int r = max_H[D].ss; // cerr << row << " " << l << " " << r << " " << max_H[S].ff << " " << max_H[D].ff << " lr\n"; if(D > S) swap(D,S); return tableX.get_max(D,S).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...