Official

C - Move One Card Editorial by en_translator Editorial for printing


The operation in the problem statement can be rephrased as follows:

  • Choose a segment \([l,r]\) of \(A\), and apply a left or right cyclic shift to \(A _ l,A _ {l+1},\ldots,A _ r\) by one element.

We will represent an operation by a pair of the segment \([l,r]\) and the direction \(\lbrace\)L\(,\) R\(\rbrace\).

Consider the property satisfied by \([l,r]\) in the operation of making \(A\) equal to \(B\) when the answer is Yes.

If \(A=B\) from the beginning, it is sufficient to set \(l=r\). Now we assume that \(A\ne B\) initially.

Let \(m\) be the smallest \(i\) such that \(A _ i\ne B _ i\), and \(M\) be the largest such \(i\). Unless \(m\in[l,r]\), the value of \(A_m\) does not change, so \(m\in[l,r]\). Likewise, \(M\in[l,r]\), so \([m,M]\subseteq[l,r]\).

Assume that \(l\lt m\) and consider the cases of applying a left or right cyclic shift.

  • If a right cyclic shift makes \(A\) equal to \(B\), \(A _ r=B _ l\) and \(A _ i=B _ {i+1}\ (l\le i\lt r)\). By definition of \(m\), \(A _ i=B _ i\ (l\le i\lt m)\), so \(A _ r=B _ l=A _ l=B _ {l+1}=A _ {l+1}=\cdots=A _ {m-2}=B _ {m-1}=A _ {m-1}=B _ m\). Hence, applying a right cyclic shift to \([m,r]\) yields the same sequence.
  • If a left cyclic shift makes \(A\) equal to \(B\), \(A _ l=B _ r\) and \(A _ {i+1}=B _ i\ (l\le i\lt r)\). By definition of \(m\), \(A _ i=B _ i\ (l\le i\lt m)\), so \(B _ r=A _ l=B _ l=A _ {l+1}=B _ {l+1}=\cdots=B _ {m-2}=A _ {m-1}=B _ {m-1}=A _ m\). Hence, applying a right cyclic shift to \([m,r]\) yields the same sequence.

Likewise, if \(A\) can be made equal to \(B\) by applying the operation on \([l,r]\) with \(M\lt r\), then \(A\) can be made equal to \(B\) by applying the operation on \([l,M]\).

Therefore, if the answer is Yes, then \(A\) can be made equal to \(B\) by applying the operation on \([m,M]\).

By the discussion above, the answer can be found by the following algorithm:

  1. While \(A\) and \(B\) are non-empty and the last elements have the same value, remove the last elements from \(A\) and \(B\).
  2. While \(A\) and \(B\) are non-empty and the first elements have the same value, remove the first elements from \(A\) and \(B\).
  3. The answer is Yes if \(A\) and \(B\) are empty, and applying a right or left cyclic shift by one to \(A\) makes it equal to \(B\); otherwise, the answer is No.

With appropriate implementation, the algorithm runs in \(O(N)\) time.

The following is sample code.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int N;
    cin >> N;
    vector<int> A(N), B(N);
    for (auto&& a : A) cin >> a;
    for (auto&& b : B) cin >> b;
    
    // Remove the trailing common elements
    while (!A.empty() && A.back() == B.back()) {
        A.pop_back();
        B.pop_back();
    }
    
    // Reverse them
    ranges::reverse(A);
    ranges::reverse(B);
    // Remove the trailing common elements
    while (!A.empty() && A.back() == B.back()) {
        A.pop_back();
        B.pop_back();
    }
    
    // If A == B
    if (A.empty()) { // Yes
        cout << "Yes" << endl;
        return 0;
    }
    
    // Try left cyclic shift
    auto A_lshift = A;
    ranges::rotate(A_lshift, begin(A_lshift) + 1);
    if (A_lshift == B) {
        cout << "Yes" << endl;
        return 0;
    }
    
    // and right cyclic shift
    auto A_rshift = A;
    ranges::rotate(A_rshift, end(A_rshift) - 1);
    if (A_rshift == B) {
        cout << "Yes" << endl;
        return 0;
    }
    
    cout << "No" << endl;
    return 0;
}

posted:
last update: