Submission #1296037

#TimeUsernameProblemLanguageResultExecution timeMemory
1296037lucas110550Hieroglyphs (IOI24_hieroglyphs)C++20
19 / 100
132 ms39944 KiB
#include <vector> #include <unordered_set> #include <unordered_map> #include <queue> #include <algorithm> using namespace std; vector<int> ucs(vector<int> A, vector<int> B) { const int INF = 1000000000; int n = (int)A.size(); int m = (int)B.size(); // Build sets for A and B unordered_set<int> setA, setB; for (int x : A) setA.insert(x); for (int x : B) setB.insert(x); // common = set(A) & set(B) unordered_set<int> common; for (int x : setA) { if (setB.count(x)) { common.insert(x); } } if (common.empty()) { return {}; } // listB[x] = list of positions of x in B unordered_map<int, vector<int>> listB; for (int x : common) { listB[x] = vector<int>(); // ensure key exists } for (int j = 0; j < m; ++j) { int x = B[j]; if (common.count(x)) { listB[x].push_back(j); } } // count_in_A[x] = occurrences of x in A unordered_map<int, int> count_in_A; for (int a : A) { if (common.count(a)) { count_in_A[a]++; // default 0 then increment } } // available[x] = min(count_in_A[x], len(listB[x])) unordered_map<int, int> available; for (int x : common) { int cntA = count_in_A[x]; int cntB = (int)listB[x].size(); available[x] = min(cntA, cntB); } int L = 0; for (int x : common) { L += available[x]; } if (L == 0) { return {}; } // threshold_arr[x] unordered_map<int, int> threshold_arr; for (int x : common) { if (available[x] > 0) { int index_in_list = (int)listB[x].size() - available[x]; threshold_arr[x] = listB[x][index_in_list]; } else { threshold_arr[x] = INF; } } // min-heap over (threshold, value) using PII = pair<int, int>; priority_queue<PII, vector<PII>, greater<PII>> heap_over_y; for (int x : common) { if (available[x] > 0) { heap_over_y.push({threshold_arr[x], x}); } } int lastB = -1; vector<int> U; for (int i = 0; i < n; ++i) { int x = A[i]; if (!common.count(x) || available[x] <= 0) { continue; } int threshold = INF; if (available[x] > 1) { int future_avail = available[x] - 1; int index_in_list = (int)listB[x].size() - future_avail; int candidate = listB[x][index_in_list]; threshold = candidate; } // Clean the heap top: discard outdated entries or those with y == x while (!heap_over_y.empty()) { PII top = heap_over_y.top(); int th = top.first; int y = top.second; int current_threshold_y = INF; auto it = threshold_arr.find(y); if (it != threshold_arr.end()) { current_threshold_y = it->second; } if (y == x || th != current_threshold_y) { heap_over_y.pop(); } else { break; } } if (!heap_over_y.empty()) { int th = heap_over_y.top().first; if (th < threshold) { threshold = th; } } // pos = bisect_right(listB[x], lastB) vector<int> &positions = listB[x]; auto itPos = upper_bound(positions.begin(), positions.end(), lastB); size_t pos = itPos - positions.begin(); if (pos >= positions.size()) { continue; } bool found = false; int j_candidate = -1; while (pos < positions.size()) { int j = positions[pos]; if (j < threshold) { found = true; j_candidate = j; break; } ++pos; } if (!found) { continue; } U.push_back(x); lastB = j_candidate; available[x] -= 1; if (available[x] == 0) { threshold_arr[x] = INF; } else { int index_in_list = (int)positions.size() - available[x]; int new_threshold = positions[index_in_list]; threshold_arr[x] = new_threshold; heap_over_y.push({new_threshold, x}); } } if ((int)U.size() == L) { return U; } else { return vector<int>{-1}; } }
#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...