제출 #1251758

#제출 시각아이디문제언어결과실행 시간메모리
1251758Zbyszek99장애물 (IOI25_obstacles)C++20
58 / 100
1960 ms142276 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; int max_H[200001]; int X[200001]; int Y[200001]; vi pref; 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); } } void rek(int l, int r, int pref_max, int pop) { cerr << l << " " << r << " " << pref_max << " " << pop << " rek\n"; 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; } } cerr << down_ok << " ok\n"; vector<pii> segs; if(down_ok != 0) split(l,r,pref[down_ok-1],segs); else segs.pb({l,r}); int pop2 = pop; if(down_ok != pref_max) { int l2 = down_ok; int r2 = pref_max; int up = down_ok; int min_col = tableX.get_min(l,r).ss; while(l2 <= r2) { int mid = (l2+r2)/2; if(tableY.get_min(pref[down_ok],pref[mid]).ff > X[min_col]) { up = mid; l2 = mid+1; } else { r2 = mid-1; } } cerr << up << " up\n"; if(up != pref_max) { pop2 = pref[up]; } } if(down_ok == 0) { rep2(i,l,r) { max_H[i] = pop2; } 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,pop2); } else { rek(it.ff,it.ss,down_ok-1,down_ok-1); } } } 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); int pop = -1; rep(i,siz(T)) { if(Y[i] >= pop) { pref.pb(i); pop = Y[i]; } } rek(0,siz(H)-1,siz(pref)-1,pref.back()); } bool can_reach(int L, int R, int S, int D) { int row = min(max_H[S],max_H[D]); 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...