Submission #805338

#TimeUsernameProblemLanguageResultExecution timeMemory
805338thimote75Railway Trip (JOI17_railway_trip)C++14
100 / 100
500 ms27280 KiB
#include <bits/stdc++.h> using namespace std; using idata = vector<int>; using igrid = vector<idata>; template <typename A, typename B> string to_string(pair<A, B> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; } string to_string(string s) { return s; } template <typename T> string to_string(T v) { bool first = true; string res = "["; for (const auto &x : v) { if (!first) res += ", "; first = false; res += to_string(x); } res += "]"; return res; } void dbg_out() { cout << endl; } template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << to_string(H); dbg_out(T...); } #ifdef DEBUG #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__) #else #define dbg(...) #endif struct Container { map<int, int> m; void insert(int height, int pos) { auto it = m.upper_bound(height); while (it != m.begin()) { it --; int h = (*it).first; m.erase(h); it = m.upper_bound(height); } m.insert({ height, pos }); } int query (int height) { auto it = m.lower_bound(height); if (it == m.end()) return -1; return (*it).second; } }; idata heights; idata left_road; idata right_road; igrid left_road_2k; igrid right_road_2k; int N, K, Q; const int MAXK = 20; bool intersects (pair<int, int> a, pair<int, int> b) { if (b < a) swap (a, b); return a.second >= b.first; } pair<int, int> create (pair<int, int> start, int k) { int l = start.first; int r = start.second; int nl = min( left_road_2k[l][k], left_road_2k[r][k] ); int nr = max( right_road_2k[l][k], right_road_2k[r][k] ); return { nl, nr }; } pair<pair<int, int>, int> jump_until (pair<int, int> start, pair<int, int> other) { int count = 0; for (int k = MAXK - 1; k >= 0; k --) { pair<int, int> potential = create(start, k); if (intersects(potential, other)) continue ; start = potential; count += 1 << k; } return { start, count }; } void blf () { left_road_2k .resize(N, idata(MAXK, 0)); right_road_2k.resize(N, idata(MAXK, N - 1)); for (int i = 0; i < N; i ++) { left_road_2k[i][0] = left_road[i]; right_road_2k[i][0] = right_road[i]; } for (int k = 0; k + 1 < MAXK; k ++) { for (int i = 0; i < N; i ++) { left_road_2k[i][k + 1] = min( left_road_2k[ left_road_2k[i][k]][k], left_road_2k[right_road_2k[i][k]][k] ); right_road_2k[i][k + 1] = max( right_road_2k[ left_road_2k[i][k]][k], right_road_2k[right_road_2k[i][k]][k] ); } } } idata bfs (int start) { queue<int> q; idata answer(N, 1e9); answer[start] = 0; q.push(start); while (q.size() != 0) { int curr = q.front(); q.pop(); for (int next : { left_road[curr], right_road[curr] }) { if (next == -1) continue ; if (answer[next] != 1e9) continue ; q.push(next); answer[next] = answer[curr] + 1; } } return answer; } int main () { cin >> N >> K >> Q; heights.resize(N); for (int i = 0; i < N; i ++) cin >> heights[i]; left_road.resize(N, -1); Container cnt; for (int i = 0; i < N; i ++) { left_road[i] = cnt.query(heights[i]); if (i == 0) left_road[i] = 0; cnt.insert(heights[i], i); } cnt.m.clear(); right_road.resize(N, -1); for (int i = N - 1; i >= 0; i --) { right_road[i] = cnt.query(heights[i]); if (i + 1 == N) right_road[i] = i; cnt.insert(heights[i], i); } blf(); for (int q = 0; q < Q; q ++) { int a, b; cin >> a >> b; a --; b --; if (a > b) swap(a, b); const auto data1 = jump_until({ a, a }, { b, b }); const auto data2 = jump_until({ b, b }, data1.first); cout << data1.second + data2.second << "\n"; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...