제출 #1326527

#제출 시각아이디문제언어결과실행 시간메모리
1326527johnadilBitaro’s Party (JOI18_bitaro)C++20
7 / 100
2094 ms5860 KiB
#include <iostream> #include <vector> #include <algorithm> using namespace std; const int BLOCK_SIZE = 320; const int INF = 1e9; int main() { // Optimize standard I/O operations for performance ios_base::sync_with_stdio(false); cin.tie(NULL); int n, m, q; if (!(cin >> n >> m >> q)) return 0; // We store the reverse graph to look back at incoming edges vector<vector<int>> rev_adj(n + 1); for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; rev_adj[v].push_back(u); } // top_paths[v] stores up to BLOCK_SIZE pairs of {distance, origin_node} vector<vector<pair<int, int>>> top_paths(n + 1); // used_time array replaces a boolean visited array to avoid O(N) resets vector<int> used_time(n + 1, 0); int current_time = 0; // Precomputation phase for (int v = 1; v <= n; v++) { current_time++; vector<pair<int, int>> candidates; // A node can always reach itself with a distance of 0 candidates.push_back({0, v}); // Gather all precomputed paths from incoming edges for (int u : rev_adj[v]) { for (auto p : top_paths[u]) { candidates.push_back({p.first + 1, p.second}); } } // Sort candidates by distance in descending order sort(candidates.rbegin(), candidates.rend()); // Greedily pick the top distinct origins up to the BLOCK_SIZE limit for (auto p : candidates) { if (used_time[p.second] != current_time) { used_time[p.second] = current_time; top_paths[v].push_back(p); if (top_paths[v].size() == BLOCK_SIZE) { break; } } } } vector<int> dist(n + 1, -1); vector<bool> blocked(n + 1, false); // Query phase for (int i = 0; i < q; i++) { int target, y_count; cin >> target >> y_count; vector<int> y(y_count); for (int j = 0; j < y_count; j++) { cin >> y[j]; blocked[y[j]] = true; } if (y_count >= BLOCK_SIZE) { // Heavy Query: Standard DAG Longest Path DP for (int v = 1; v <= target; v++) { dist[v] = blocked[v] ? -INF : 0; for (int u : rev_adj[v]) { if (dist[u] != -INF) { dist[v] = max(dist[v], dist[u] + 1); } } } cout << (dist[target] < 0 ? -1 : dist[target]) << "\n"; } else { // Light Query: Fast lookup from precomputed top paths int ans = -1; for (auto p : top_paths[target]) { if (!blocked[p.second]) { ans = p.first; break; } } cout << ans << "\n"; } // Reset the blocked array efficiently for (int j = 0; j < y_count; j++) { blocked[y[j]] = false; } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...