제출 #1272775

#제출 시각아이디문제언어결과실행 시간메모리
1272775rxlfd314Obstacles for a Llama (IOI25_obstacles)C++20
83 / 100
239 ms45544 KiB
#include "obstacles.h" #include <bits/stdc++.h> using namespace std; using ll = long long; using ari2 = array<int, 2>; using ari3 = array<int, 3>; using arl2 = array<ll, 2>; using arl3 = array<ll, 3>; template <class T> using vt = vector<T>; #define all(x) begin(x), end(x) #define size(x) (int((x).size())) #define REP(a,b,c,d) for(int a=(b);(d)>0?a<=(c):a>=(c);a+=(d)) #define FOR(a,b,c) REP(a,b,c,1) #define ROF(a,b,c) REP(a,b,c,-1) constexpr int mxN = 200005, LOG = 17; struct DSU { int uf[mxN]; void init() { memset(uf, -1, sizeof(uf)); } int find(const int i) { return uf[i] < 0 ? i : uf[i] = find(uf[i]); } bool unite(int a, int b) { if ((a = find(a)) == (b = find(b))) return false; if (uf[a] > uf[b]) swap(a, b); uf[a] += uf[b]; uf[b] = a; return true; } } uf; struct ST { int st[mxN][LOG+1]; void init(const vt<int> &A) { const int N = size(A); FOR(i, 0, N-1) st[i][0] = A[i]; FOR(j, 1, LOG) FOR(i, 0, N-(1<<j)) st[i][j] = max(st[i][j-1], st[i+(1<<j-1)][j-1]); } int query(const int l, const int r) { const int n = 31 - __builtin_clz(r-l+1); return max(st[l][n], st[r-(1<<n)+1][n]); } } st; int N, M; void initialize(const vt<int> T, const vt<int> H) { N = size(T), M = size(H); vt<int> pmin = T, pmax = T; FOR(i, 1, N-1) { pmin[i] = min(pmin[i-1], T[i]); pmax[i] = max(pmax[i-1], T[i]); } vt<vt<int>> rem(N+1); FOR(i, 0, M-1) { int lo = 0, hi = N; while (lo < hi) { const int mid = lo + hi >> 1; if (pmin[mid] > H[i]) lo = mid + 1; else hi = mid; } rem[lo].push_back(i); } vt<vt<int>> join(N+1); st.init(H); FOR(i, 0, M-2) { int lo = 0, hi = N; while (lo < hi) { const int mid = lo + hi >> 1; if (pmax[mid] > max(H[i], H[i+1])) hi = mid; else lo = mid + 1; } join[lo].push_back(i); } set<int> active; FOR(i, 0, M-1) active.insert(i); uf.init(); FOR(x, 0, N-1) { for (const auto &i : rem[x]) if (active.count(i)) active.erase(active.find(i)); for (const auto &i : join[x]) { const auto it = active.upper_bound(i); if (it == active.end() || it == active.begin()) continue; const int j = *prev(it), k = *it; if (T[x] > st.query(j, k)) { uf.unite(j, k); active.erase(active.find(H[j] < H[k] ? k : j)); } } } } bool can_reach(int L, int R, int S, int D) { return uf.find(S) == uf.find(D); }
#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...