如果对于某个字符 s∈S 且 CA(s)≤CB(s),就说明 UCS 里出现的所有 s 刚好和 A 全部匹配上,把 s 在 A 里所有出现的位置记为 s-critical-in-A. 类似地有 s-critical-in-B. 把 s 记为 critical char of A/B,s 在 A,B 里面的下标记为 critical position.
vi calculate_ucs(vi &A, vi &B, vi &pickA, vi &pickB){ int n = A.size(), m = B.size(); vi cntA(V, 0), cntB(V, 0); for (int x : A) cntA[x]++; for (int x : B) cntB[x]++;
vi partA, partB; for (int i = 0; i < n; i++) if (cntA[A[i]] <= cntB[A[i]]) partA.push_back(i); for (int i = 0; i < m; i++) if (cntB[B[i]] < cntA[B[i]]) partB.push_back(i); partA.push_back(n), partB.push_back(m);
Sequence seqA(A), seqB(B); Sequence skipA(A), skipB(B); auto pA = partA.begin(), pB = partB.begin(); skipA.move_to(*pA), skipB.move_to(*pB); vi candidate;
while (*pA != n or *pB != m) { bool can_putA = true, can_putB = true;
if (*pA != n) { // can we fill A[i]? can_putA &= seqB.remain(A[*pA]) > skipB.remain(A[*pA]);
if (*pB != m) can_putA &= skipA.remain(B[*pB]) >= skipB.remain(B[*pB]); } else can_putA = false;
if (*pB != m) { can_putB &= seqA.remain(B[*pB]) > skipA.remain(B[*pB]);
vi prepare(vi &A, vi &B){ int n = A.size(), m = B.size(); std::vector<vi> appear(V); for (int i = 0; i < m; i++) appear[B[i]].push_back(i); for (auto &v : appear) v.push_back(m);
vi last(V, -1); std::vector<std::pair<int, int>> stack; stack.push_back({-1, -1});
vi match(n, -1); for (int i = 0; i < n; i++) { int L = last[A[i]]; int where = std::lower_bound(stack.begin(), stack.end(), std::make_pair(L, -1))->second; if (where != m) where = *std::upper_bound(appear[A[i]].begin(), appear[A[i]].end(), where); match[i] = where;
boolcheck(vi &A, vi &B, vi &c, vi &posA, vi &posB){ int n = A.size(), m = B.size(), t = c.size(); vi matchA = prepare(A, B); vi atA(n, -1), prev_atA(n + 1, -1); for (int i = 0; i < t; i++) { atA[posA[i]] = i; prev_atA[posA[i] + 1] = i; } for (int i = 1; i <= n; i++) if (prev_atA[i] == -1) prev_atA[i] = prev_atA[i - 1]; for (int i = 0; i < n; i++) { if (atA[i] != -1) continue;
int index = prev_atA[i]; if (index != -1 && matchA[i] <= posB[index]) returnfalse; } returntrue; }
vi ucs(vi A, vi B){ vi posa, posb; auto ans = calculate_ucs(A, B, posa, posb);
if (ans.size() == 1 && ans[0] == -1) return {-1};
if (!check(A, B, ans, posa, posb)) return {-1}; if (!check(B, A, ans, posb, posa)) return {-1};
return ans; }
intmain(){ int n, m; std::cin >> n >> m; vi A(n), B(m); for (int &x : A) std::cin >> x; for (int &x : B) std::cin >> x; vi result = ucs(A, B); std::cout << result.size() << '\n'; for (auto x : result) std::cout << x << " "; std::cout << "\n"; }