Submission #1263185

#TimeUsernameProblemLanguageResultExecution timeMemory
1263185Aviansh장애물 (IOI25_obstacles)C++20
83 / 100
1070 ms175268 KiB
#include <bits/stdc++.h> using namespace std; // -------------------- Segment Tree -------------------- struct segTree { int *st; int n; segTree(int siz){ int x = ceil(log2(siz)); x++; n = siz - 1; st = new int[(1<<x)]; fill(st, st+(1<<x), 0); } void rupdate(int l, int r, int ind, int i, int val){ if(i < l || i > r) return; if(l == r){ st[ind] = val; return; } int mid = (l+r)/2; rupdate(l, mid, ind*2+1, i, val); rupdate(mid+1, r, ind*2+2, i, val); st[ind] = min(st[ind*2+1], st[ind*2+2]); } void update(int i, int val){ rupdate(0, n, 0, i, val); } int rquery(int l, int r, int s, int e, int ind){ if(e < l || s > r) return 1e9; if(s <= l && r <= e) return st[ind]; int mid = (l+r)/2; return min(rquery(l, mid, s, e, ind*2+1), rquery(mid+1, r, s, e, ind*2+2)); } int query(int l, int r){ return rquery(0, n, l, r, 0); } // return {index, value} pair<int,int> rleftmost(int l, int r, int s, int e, int ind, int val){ if(e < l || s > r) return {1e9,1e9}; if(st[ind] > val) return {1e9,1e9}; if(l == r) return {l, st[ind]}; int mid = (l+r)/2; pair<int,int> p = rleftmost(l, mid, s, e, ind*2+1, val); if(p.second <= val) return p; // ✅ fixed return rleftmost(mid+1, r, s, e, ind*2+2, val); } int lefmost(int l, int r, int val){ return rleftmost(0, n, l, r, 0, val).first; } pair<int,int> rrigtmost(int l, int r, int s, int e, int ind, int val){ if(e < l || s > r) return {1e9,1e9}; if(st[ind] > val) return {1e9,1e9}; if(l == r) return {l, st[ind]}; int mid = (l+r)/2; pair<int,int> p = rrigtmost(mid+1, r, s, e, ind*2+2, val); if(p.second <= val) return p; // ✅ fixed return rrigtmost(l, mid, s, e, ind*2+1, val); } int rigmost(int l, int r, int val){ return rrigtmost(0, n, l, r, 0, val).first; } }; // -------------------- Globals -------------------- const int maxm = 2e5+5; const int lg = 20; long long conv(array<int,2>a){ return (((long long)a[0])<<20)|a[1]; } segTree seg(maxm); unordered_map<long long,vector<pair<int,array<int,2>>>> g; unordered_map<long long,vector<pair<int,array<int,2>>>> parl; unordered_map<long long,vector<pair<int,array<int,2>>>> parr; vector<array<int,2>> rs; // -------------------- DFS -------------------- void dfs(pair<int,array<int,2>> node){ array<int,2> st = node.second; int req = 1e9; if(g[conv(st)].size()){ req = g[conv(st)][0].first; } if(parl.find(conv(st)) != parl.end()){ return; } int reql = seg.lefmost(st[0], st[1], req); int reqr = seg.rigmost(st[0], st[1], req); parl[conv(st)] = vector<pair<int,array<int,2>>>(lg, {-1, st}); parr[conv(st)] = vector<pair<int,array<int,2>>>(lg, {1e9, st}); if(g[conv(st)].size() == 0){ return; } dfs(g[conv(st)][0]); array<int,2> las = g[conv(st)][0].second; vector<pair<int,array<int,2>>> temp(lg); temp[0] = {reql, g[conv(st)][0].second}; for(int i=1;i<lg;i++){ temp[i] = {max(temp[i-1].first, parl[conv(las)][i-1].first), parl[conv(las)][i-1].second}; las = temp[i].second; } parl[conv(st)] = temp; temp[0] = {reqr, g[conv(st)][0].second}; las = g[conv(st)][0].second; for(int i=1;i<lg;i++){ temp[i] = {min(temp[i-1].first, parr[conv(las)][i-1].first), parr[conv(las)][i-1].second}; las = temp[i].second; } parr[conv(st)] = temp; } // -------------------- Initialize -------------------- void initialize(vector<int> T, vector<int> H) { int n = T.size(); int m = H.size(); vector<array<int,2>> elems; for(int i=0;i<m;i++){ seg.update(i, H[i]); elems.push_back({H[i], i}); } sort(elems.begin(), elems.end()); segTree stt(n); for(int i=0;i<n;i++){ stt.update(i, T[i]); } // current ranges int las = -1; for(int i=0;i<m;i++){ if(T[0] <= H[i]){ if(las != -1){ rs.push_back({las, i-1}); } las = -1; } else { if(las == -1) las = i; } } if(las != -1) rs.push_back({las, m-1}); // graph building set<array<int,2>> rangs; map<array<int,2>,int> mp; auto it = elems.begin(); for(int i=0;i<n;i++){ while(it!=elems.end() && (*it)[0] < T[i]){ int ind = (*it)[1]; array<int,2> rang = {ind, ind}; bool wor = 0; int x = 0; array<int,2> up = {-1,-1}; auto itup = rangs.lower_bound(rang); if(itup != rangs.end()){ up = *itup; if(up[0] == ind+1){ rang[1] = up[1]; x = stt.query(mp[up], i); if(x > seg.query(up[0], up[1])){ wor = 1; } rangs.erase(up); } } auto itdow = rangs.lower_bound(rang); if(itdow != rangs.begin()){ itdow--; array<int,2> dow = *itdow; if(dow[1] == ind-1){ rang[0] = dow[0]; int f = stt.query(mp[dow], i); if(f > seg.query(dow[0], dow[1])){ g[conv(dow)].push_back({f, rang}); } rangs.erase(dow); } } rangs.insert(rang); if(wor){ g[conv(up)].push_back({x, rang}); } it++; } } for(array<int,2>a: rs){ dfs({T[0], a}); } } // -------------------- LCA -------------------- array<int,2> lca(array<int,2> a, array<int,2> b){ if(a == b){ return {1000000000, -1}; } int l = -1; int r = 1e9; for(int i=lg-1;i>=0;i--){ pair<int,array<int,2>> p = parl[conv(a)][i]; array<int,2> posa = p.second; if(posa[0] <= b[0] && b[1] <= posa[1]) continue; l = max(l, p.first); r = min(r, p.first); a = posa; } for(int i=lg-1;i>=0;i--){ pair<int,array<int,2>> p = parl[conv(b)][i]; array<int,2> posb = p.second; if(posb[0] <= a[0] && a[1] <= posb[1]) continue; l = max(l, p.first); r = min(r, p.first); b = posb; } if(a[0] <= b[0] && b[1] <= a[1]){ l = max(l, parl[conv(b)][0].first); r = min(r, parr[conv(b)][0].first); b = parl[conv(b)][0].second; } else if(b[0] <= a[0] && a[1] <= b[1]){ swap(a, b); l = max(l, parl[conv(b)][0].first); r = min(r, parr[conv(b)][0].first); b = parl[conv(b)][0].second; } else{ l = max(l, parl[conv(b)][0].first); r = min(r, parr[conv(b)][0].first); b = parl[conv(b)][0].second; swap(a, b); l = max(l, parl[conv(b)][0].first); r = min(r, parr[conv(b)][0].first); b = parl[conv(b)][0].second; } return {l, r}; // ✅ fixed } // -------------------- can_reach -------------------- bool can_reach(int L, int R, int S, int D) { if(S > D) swap(S, D); array<int,2> rangs = *(upper_bound(rs.begin(), rs.end(), (array<int,2>){S,1000000000})-1); array<int,2> rangd = *(upper_bound(rs.begin(), rs.end(), (array<int,2>){D,1000000000})-1); if(parl[conv(rangs)][lg-1].second != parl[conv(rangd)][lg-1].second){ return 0; } array<int,2> arr = lca(rangs, rangd); if(arr[0] < L || arr[1] > R) return 0; return 1; }
#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...