Submission #1295523

#TimeUsernameProblemLanguageResultExecution timeMemory
1295523lucas110550Hieroglyphs (IOI24_hieroglyphs)C++20
0 / 100
1095 ms11348 KiB
#include <vector> #include <unordered_map> #include <utility> #include <algorithm> using std::vector; using std::unordered_map; using std::pair; class SegmentTree { public: SegmentTree(int size) : n(size) { tree.assign(4 * n, {0, -1}); } void update(int pos, int val) { update_tree(0, 0, n - 1, pos, val); } // query range [l, r] pair<int, int> query(int l, int r) { if (l > r) return {0, -1}; return query_tree(0, 0, n - 1, l, r); } private: int n; vector<pair<int, int>> tree; // {value, index} void update_tree(int node, int start, int end, int pos, int val) { if (start == end) { tree[node] = {val, pos}; return; } int mid = (start + end) / 2; if (pos <= mid) { update_tree(2 * node + 1, start, mid, pos, val); } else { update_tree(2 * node + 2, mid + 1, end, pos, val); } auto left = tree[2 * node + 1]; auto right = tree[2 * node + 2]; if (left.first > right.first) { tree[node] = left; } else if (right.first > left.first) { tree[node] = right; } else { // tie-breaker: prefer larger index if (left.second >= right.second) tree[node] = left; else tree[node] = right; } } pair<int, int> query_tree(int node, int start, int end, int l, int r) { if (r < start || end < l) { return {0, -1}; } if (l <= start && end <= r) { return tree[node]; } int mid = (start + end) / 2; pair<int, int> left_res = {0, -1}; pair<int, int> right_res = {0, -1}; if (l <= mid) { left_res = query_tree(2 * node + 1, start, mid, l, r); } if (r > mid) { right_res = query_tree(2 * node + 2, mid + 1, end, l, r); } if (left_res.first > right_res.first) { return left_res; } else if (right_res.first > left_res.first) { return right_res; } else { // tie-breaker: prefer larger index if (left_res.second >= right_res.second) return left_res; else return right_res; } } }; vector<int> ucs(vector<int> A, vector<int> B) { int n = (int)A.size(); int m = (int)B.size(); if (m == 0) return {}; // Build nextB: value -> list of indices in B unordered_map<int, vector<int>> nextB; for (int idx = 0; idx < m; ++idx) { int val = B[idx]; nextB[val].push_back(idx); } vector<int> f(m + 1, 0); vector<int> prev(m + 1, -1); int size = m; SegmentTree seg(size); for (int i = 0; i < n; ++i) { int a = A[i]; auto it = nextB.find(a); if (it == nextB.end()) continue; // Important: to match Python behavior, we must process indices of B in // ascending order, but since we’re using dp with segment tree and // referring only to prefix [0..j-1], this is fine. const vector<int>& indices = it->second; for (int j : indices) { int M, k; if (j > 0) { auto res = seg.query(0, j - 1); M = res.first; k = res.second; } else { M = 0; k = -1; } int candidate = M + 1; if (candidate > f[j]) { f[j] = candidate; prev[j] = k; seg.update(j, candidate); } } } int L = 0; int j0 = -1; for (int j = 0; j < m; ++j) { if (f[j] > L) { L = f[j]; j0 = j; } } if (L == 0) return {}; vector<int> U; int j = j0; int current_length = L; while (current_length > 0) { U.push_back(B[j]); j = prev[j]; current_length--; } std::reverse(U.begin(), U.end()); return U; }
#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...