Submission #1132091

#TimeUsernameProblemLanguageResultExecution timeMemory
1132091AndrijaMBitaro’s Party (JOI18_bitaro)C++20
100 / 100
750 ms152732 KiB
#include <algorithm> #include <cassert> #include <iostream> #include <vector> #include <set> using namespace std; using ll = long long; using vl = vector<ll>; // Overload input operator for vector istream &operator>>(istream &is, vl &a) { for (auto &x : a) cin >> x; return is; } constexpr int MAX_NODES = 200200; constexpr int BLOCK_SIZE = 100; vector<int> forwardGraph[MAX_NODES], reverseGraph[MAX_NODES]; // Function to process least arrays for all nodes void preprocessLeastArrays(int n, vector<vector<pair<int, int>>> &least) { vector<int> used(n + 1, -1); least[1] = {{0, 1}}; for (int i = 2; i <= n; i++) { vector<int> tempStorage; // Traverse reverse edges for (auto &neighbor : reverseGraph[i]) { for (auto &[dist, node] : least[neighbor]) { if (used[node] < 0) tempStorage.push_back(node); used[node] = max(used[node], dist + 1); } } // Update least array for node `i` least[i].emplace_back(0, i); for (auto &x : tempStorage) { least[i].emplace_back(used[x], x); } // Sort and trim to BLOCK_SIZE sort(least[i].begin(), least[i].end(), greater<>()); if (least[i].size() > BLOCK_SIZE) { least[i].resize(BLOCK_SIZE); } // Reset `used` array for (auto &x : tempStorage) { used[x] = -1; } } } // Function to handle queries void handleQuery(int t, int y, const vector<int> &blocked, const vector<vector<pair<int, int>>> &least) { set<int> blockedSet(blocked.begin(), blocked.end()); if (y >= BLOCK_SIZE) { // Dynamic programming for large number of blocked nodes vector<int> dp(t + 1, -1); dp[t] = 0; for (int node = t; node >= 1; node--) { if (dp[node] == -1) continue; for (const auto &neighbor : reverseGraph[node]) { dp[neighbor] = max(dp[neighbor], dp[node] + 1); } } int maxDistance = -1; for (int node = 1; node <= t; node++) { if (!blockedSet.count(node)) { maxDistance = max(maxDistance, dp[node]); } } cout << maxDistance << "\n"; } else { // Direct computation for small number of blocked nodes int maxDistance = -1; for (const auto &[dist, node] : least[t]) { if (!blockedSet.count(node)) { maxDistance = max(maxDistance, dist); } } cout << maxDistance << "\n"; } } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n, m, q; cin >> n >> m >> q; // Input graph edges for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; forwardGraph[u].push_back(v); reverseGraph[v].push_back(u); } // Prepare least arrays for all nodes vector<vector<pair<int, int>>> least(n + 1); preprocessLeastArrays(n, least); // Process queries for (int i = 0; i < q; i++) { int t, y; cin >> t >> y; vector<int> blocked(y); for (int j = 0; j < y; j++) { cin >> blocked[j]; } handleQuery(t, y, blocked, least); } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...