Problem:
Score : 1200 points

Problem Statement

You are given a permutation of 1,2,...,N: p_1,p_2,...,p_N. Determine if the state where p_i=i for every i can be reached by performing the following operation any number of times:

Choose three elements p_{i-1},p_{i},p_{i+1} (2\leq i\leq N-1) such that p_{i-1}>p_{i}>p_{i+1} and reverse the order of these three.

Constraints

3 \leq N \leq 3 × 10^5

p_1,p_2,...,p_N is a permutation of 1,2,...,N.

Input

Input is given from Standard Input in the following format:

N
p_1
:
p_N

Output

If the state where p_i=i for every i can be reached by performing the operation, print Yes; otherwise, print No.

Sample Input 1

5
5
2
1
4
3

Sample Output 1

Yes

The state where p_i=i for every i can be reached as follows:

Reverse the order of p_1,p_2,p_3. The sequence p becomes 1,2,5,4,3.

Reverse the order of p_3,p_4,p_5. The sequence p becomes 1,2,3,4,5.

Sample Input 2

4
3
2
4
1

Sample Output 2

No

Sample Input 3

7
3
2
1
6
5
4
7

Sample Output 3

Yes

Sample Input 4

6
5
3
4
1
2
6

Sample Output 4

No

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; (i) < (int)(n); ++ (i))
#define REP3(i, m, n) for (int i = (m); (i) < (int)(n); ++ (i))
#define REP_R(i, n) for (int i = int(n) - 1; (i) >= 0; -- (i))
#define REP3R(i, m, n) for (int i = int(n) - 1; (i) >= (int)(m); -- (i))
#define ALL(x) begin(x), end(x)
#define dump(x) cerr << #x " = " << x << endl
#define unittest_name_helper(counter) unittest_ ## counter
#define unittest_name(counter) unittest_name_helper(counter)
#define unittest __attribute__((constructor)) void unittest_name(__COUNTER__) ()
using ll = long long;
using namespace std;
template <class T> using reversed_priority_queue = priority_queue<T, vector<T>, greater<T> >;
template <class T, class U> inline void chmax(T & a, U const & b) { a = max<T>(a, b); }
template <class T, class U> inline void chmin(T & a, U const & b) { a = min<T>(a, b); }
template <typename X, typename T> auto vectors(X x, T a) { return vector<T>(x, a); }
template <typename X, typename Y, typename Z, typename... Zs> auto vectors(X x, Y y, Z z, Zs... zs) { auto cont = vectors(y, z, zs...); return vector<decltype(cont)>(x, cont); }
template <typename T> ostream & operator << (ostream & out, vector<T> const & xs) { REP (i, int(xs.size()) - 1) out << xs[i] << ' '; if (not xs.empty()) out << xs.back(); return out; }

template <class Monoid>
struct segment_tree {
    typedef typename Monoid::underlying_type underlying_type;
    int n;
    vector<underlying_type> a;
    Monoid mon;
    segment_tree() = default;
    segment_tree(int a_n, underlying_type initial_value = Monoid().unit(), Monoid const & a_mon = Monoid()) : mon(a_mon) {
        n = 1; while (n < a_n) n *= 2;
        a.resize(2 * n - 1, mon.unit());
        fill(a.begin() + (n - 1), a.begin() + ((n - 1) + a_n), initial_value); // set initial values
        REP_R (i, n - 1) a[i] = mon.append(a[2 * i + 1], a[2 * i + 2]); // propagate initial values
    }
    void point_set(int i, underlying_type z) { // 0-based
        assert (0 <= i and i <= n);
        a[i + n - 1] = z;
        for (i = (i + n) / 2; i > 0; i /= 2) { // 1-based
            a[i - 1] = mon.append(a[2 * i - 1], a[2 * i]);
        }
    }
    underlying_type range_concat(int l, int r) { // 0-based, [l, r)
        assert (0 <= l and l <= r and r <= n);
        underlying_type lacc = mon.unit(), racc = mon.unit();
        for (l += n, r += n; l < r; l /= 2, r /= 2) { // 1-based loop, 2x faster than recursion
            if (l % 2 == 1) lacc = mon.append(lacc, a[(l ++) - 1]);
            if (r % 2 == 1) racc = mon.append(a[(-- r) - 1], racc);
        }
        return mon.append(lacc, racc);
    }
};
struct plus_monoid {
    typedef int underlying_type;
    int unit() const { return 0; }
    int append(int a, int b) const { return a + b; }
};

bool check(int n, vector<int> p) {
    segment_tree<plus_monoid> segtree[2][2];
    REP (is_odd, 2) REP (is_right, 2) {
        segtree[is_odd][is_right] = segment_tree<plus_monoid>(n);
    }
    REP (i, n) {
        if (p[i] % 2 != i % 2) {
            return false;
        }
        segtree[i & 1][true].point_set(p[i], 1);
    }

    int l[2] = {};
    int r[2] = {};
    REP (i, n) {
        bool is_odd = i % 2;
        int l1 = segtree[not is_odd][false].range_concat(p[i], n);
        int r1 = segtree[not is_odd][ true].range_concat(0, p[i]);
        int m1 = min(l1, r1);
        l1 -= m1;
        r1 -= m1;
        if (l[0] or l[1] or r[0] or r[1]) {
            if (not l1 and not m1 and not r1) {
                return false;
            }
        }

        l[    is_odd] -= l1;
        l[not is_odd] += m1;
        r[    is_odd] -= m1;
        r[not is_odd] += r1;
//cerr << i+1 << " " << p[i]+1 << " : " << l1  <<" / " << m1 <<" / " << r1<<
//endl;
//"    \t: " << l[0] << " " << l[1] << " / " << r[0] << " " << r[1] << endl;
        segtree[is_odd][ true].point_set(p[i], 0);
        segtree[is_odd][false].point_set(p[i], 1);
        if (l[0] and l[1]) return false;
        if (r[0] and r[1]) return false;
    }
    if (l[false]) return false;
    if (l[ true]) return false;
    if (r[false]) return false;
    if (r[ true]) return false;
    return true;
}

bool solve(int n, vector<int> p) {
    vector<int> xs;
    REP (i, n - 2) {
        if ((p[i] < p[i + 1]) == (p[i + 1] < p[i + 2])) {
            xs.push_back(i);
        }
    }
    default_random_engine gen;
    shuffle(ALL(xs), gen);
    if (xs.size() > 10) {
        xs.resize(10);
    }
    for (int i : xs) {
        swap(p[i], p[i + 2]);
        if (not check(n, p)) return false;
        swap(p[i], p[i + 2]);
    }
    return check(n, p);
}

int main() {
    int n; cin >> n;
    vector<int> p(n);
    REP (i, n) {
        cin >> p[i];
        -- p[i];
    }
    cout << (solve(n, p) ? "Yes" : "No") << endl;
    return 0;
}