제출 #932631

#제출 시각아이디문제언어결과실행 시간메모리
932631Programmer123열쇠 (IOI21_keys)C++17
37 / 100
3047 ms46704 KiB
#ifndef LOCAL #pragma GCC optimize("O3") #pragma GCC target("avx2,sse4.2") #endif #include <bits/stdc++.h> std::vector<int> find_reachable(std::vector<int> r, std::vector<int> u, std::vector<int> v, std::vector<int> c) { std::vector<int> ans(r.size(), 0); int N = r.size(); int M = u.size(); std::vector<int> newName; for (int i = 0; i < N; ++i) { newName.push_back(i); } std::shuffle(newName.begin(), newName.end(), std::default_random_engine(std::random_device{}())); auto R = r; for (int i = 0; i < N; ++i) { r[newName[i]] = R[i]; } for (int i = 0; i < M; ++i) { u[i] = newName[u[i]]; v[i] = newName[v[i]]; c[i] = c[i]; } std::vector<std::pair<int, int>> edges[N];//{dest, type} for (int i = 0; i < M; ++i) { edges[u[i]].emplace_back(v[i], c[i]); edges[v[i]].emplace_back(u[i], c[i]); } std::unordered_set<int> num[N], canReach[N]; bool eliminated[N]; for (int i = 0; i < N; ++i) { eliminated[i] = false; } int actual[N]; for (int i = 0; i < N; ++i) { actual[i] = i; } std::function<void(int)> Eliminate = [&](int x) { #ifdef LOCAL printf("Eliminating %d\n", x); #endif if (eliminated[actual[x]]) return; eliminated[actual[x]] = true; num[x].clear(); num[actual[x]].clear(); for (auto a: canReach[x]) { Eliminate(a); } for (auto a: canReach[actual[x]]) { Eliminate(a); } }; for (int i = 0; i < N; ++i) { bool seen[N]; for (int j = 0; j < N; ++j) { seen[j] = false; } seen[i] = true; std::unordered_set<int> found; std::vector<int> next[N]; std::queue<int> bfs; bfs.push(i); int TMP_THING = 0; while (!bfs.empty()) { auto n = bfs.front(); bfs.pop(); if (!found.count(r[n])) { found.insert(r[n]); for (auto a: next[r[n]]) { if (!seen[a]) { if (a < i) { TMP_THING = a; goto elim; } seen[a] = true; bfs.push(a); } } } for (auto [x, t]: edges[n]) { if (seen[x]) continue; if (found.count(t)) { if (x < i) { TMP_THING = x; goto elim; } seen[x] = true; bfs.push(x); } else { next[t].push_back(x); } } } for (int j = 0; j < N; ++j) { if (seen[j]) { num[i].insert(j); canReach[j].insert(i); } } for (auto x: canReach[i]) { if (!seen[x]) Eliminate(x); } continue; elim: TMP_THING = actual[TMP_THING]; if (eliminated[TMP_THING]) { eliminated[i] = true; for (auto x: canReach[i]) { Eliminate(x); } } else { if (num[TMP_THING].count(i)) { actual[i] = TMP_THING; for (auto x: canReach[i]) { if (!num[TMP_THING].count(x)) Eliminate(x); } } else { eliminated[i] = true; for (auto x: canReach[i]) { Eliminate(x); } } } } size_t min = INT_MAX; for (int i = 0; i < N; ++i) { if (eliminated[i]) continue; if (actual[i] != i) continue; min = std::min(min, num[i].size()); } for (int i = 0; i < N; ++i) { if (eliminated[i] || eliminated[actual[i]]) continue; ans[i] = num[actual[i]].size() == min; } auto Ans = ans; for (int i = 0; i < N; ++i) { Ans[i] = ans[newName[i]]; } return Ans; }
#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...