“Can array be turned into by these operations?” The answer is almost always: compute a canonical form (or a full set of invariants) for both and compare. To prove it you need both directions: the invariants are preserved (necessity) and any two states with equal invariants are connected (sufficiency, usually by a normalisation procedure).

OperationReachable iff
swap , each residue class has the same multiset
swap adjacent elementssame multiset
swap adjacent elements with odd (or any property of pairs)elements that can never pass each other keep their relative order
reverse any substring of length (odd )depends on : positions keep parity classes
cyclic shift of the whole array is a substring of
style prefix operationslook at difference or prefix arrays instead
operations commuteonly the count of each operation matters
bool reachableByKSwaps(vector<int> a, vector<int> b, int k) {
    int n = sz(a);
    for (int r = 0; r < k; r++) {
        vector<int> x, y;
        for (int i = r; i < n; i += k) x.push_back(a[i]), y.push_back(b[i]);
        sort(all(x)), sort(all(y));
        if (x != y) return false;
    }
    return true;
}

Normal forms

  • Operations that commute and are self-inverse (xor with a fixed mask, flipping a row or a column): each is used 0 or 1 times, so the state space is a vector space over GF(2). Reachability is a linear system; see XOR Basis.
  • Operations that move “tokens” between neighbours: track the prefix sums; each operation changes one prefix sum by .
  • If an operation can be undone, reachability is an equivalence relation; pick the lexicographically smallest member as the canonical form and compute it greedily.

Related: Constructive Algorithms, Parity and Coloring.