Official

D - Switch Seats Editorial by en_translator


How is \((a, b)\) placed in the sequence if it is satisfies the conditions in the problem statement? In fact, it turns out that it is limited to:

\[\dots, a, b, \dots, a, b, \dots\]

or

\[\dots, a, b, \dots, b, a, \dots.\]

Thus, we can see that the conditions in the problem statement is equivalent to the following:

  • The occurrences of \(a\) are not adjacent in \(A\).
  • The occurrences of \(b\) are not adjacent in \(A\).
  • Let \(p_{a,1}, p_{a,2}\) be the positions of \(a\) in \(A\), and \(p_{b,1}, p_{b,2}\)be of \(b\).
    Let \(v = (v_1, v_2, v_3, v_4)\) be the sequence \((p_{a,1}, p_{a,2}, p_{b,1}, p_{b,2})\) sorted in ascending order.
    Then, \(v_1 + 1 = v_2\) and \(v_3 + 1 = v_4\).

It also follows that if \((a, b)\) is applicable, then their occurrences should be adjacent too.
Thus, one can count all the conforming pairs \((a, b)\) by checking the criteria above for all \((A_i, A_{i+1})\) with \(1 \leq i \leq 2N-1, A_i \neq A_{i+1}\). (Note that the same pair \((a, b)\) should not be counted multiple times.) Checking the criteria for one pair costs \(\mathrm{O}(1)\) time, so the problem can be solved in a total of \(\mathrm{O}(N)\) time, which is fast enough.

  • Sample code (C++)
#include <algorithm>
#include <iostream>
#include <set>
#include <utility>
#include <vector>
using namespace std;

int main() {
  int T;
  cin >> T;
  while (T--) {
    int N;
    cin >> N;
    vector<int> A(2 * N);
    for (auto& a : A) cin >> a;

    vector<vector<int>> position(N + 1);
    for (int i = 0; i < 2 * N; i++) position[A[i]].push_back(i);

    set<pair<int, int>> answers;
    for (int i = 0; i + 1 < 2 * N; i++) {
      int a = A[i], b = A[i + 1];
      if (position[a][0] + 1 == position[a][1]) continue;
      if (position[b][0] + 1 == position[b][1]) continue;
      vector<int> v{position[a][0], position[a][1], position[b][0],
                    position[b][1]};
      sort(begin(v), end(v));
      if (v[0] + 1 == v[1] and v[2] + 1 == v[3]) {
        answers.emplace(minmax(a, b));
      }
    }
    cout << answers.size() << "\n";
  }
}

posted:
last update: