Skip to content

http://poj.openjudge.cn/practice/C26D/

C++
#include <bits/stdc++.h>
using namespace std;

static inline void appendInt(string &out, int x) {
    char buf[20];
    int len = 0;
    if (x == 0) {
        buf[len++] = '0';
    } else {
        while (x > 0) {
            buf[len++] = char('0' + x % 10);
            x /= 10;
        }
        reverse(buf, buf + len);
    }
    out.append(buf, buf + len);
}

struct Solver {
    int n, q;
    int P, R;
    bool powerOfTwo;

    vector<int> a, pos;

    // trans[0]: low -> high
    // trans[1]: high -> low
    set<int> trans[2];

    bool good(int x, int y) const {
        return (x ^ y) < n;
    }

    int type(int x) const {
        return x >= P;
    }

    bool validK(int k) const {
        return 2 <= k && k <= n - 2;
    }

    void addK(int k) {
        if (powerOfTwo || !validK(k)) return;

        int t1 = type(a[k]);
        int t2 = type(a[k + 1]);

        if (t1 != t2) {
            trans[t1].insert(k);
        }
    }

    void delK(int k) {
        if (powerOfTwo || !validK(k)) return;

        int t1 = type(a[k]);
        int t2 = type(a[k + 1]);

        if (t1 != t2) {
            trans[t1].erase(k);
        }
    }

    void init(int n_, int q_, const vector<int> &arr) {
        n = n_;
        q = q_;

        a.assign(n + 1, 0);
        pos.assign(n, 0);

        for (int i = 1; i <= n; i++) {
            a[i] = arr[i];
            pos[a[i]] = i;
        }

        powerOfTwo = (n & (n - 1)) == 0;

        trans[0].clear();
        trans[1].clear();

        if (powerOfTwo) {
            P = n;
            R = 0;
            return;
        }

        P = 1;
        while ((P << 1) < n) P <<= 1;
        R = n - P;

        for (int k = 2; k <= n - 2; k++) {
            addK(k);
        }
    }

    void doSwap(int u, int v) {
        if (u == v) return;

        vector<int> ks = {u - 1, u, v - 1, v};
        sort(ks.begin(), ks.end());
        ks.erase(unique(ks.begin(), ks.end()), ks.end());

        for (int k : ks) delK(k);

        int x = a[u];
        int y = a[v];

        swap(a[u], a[v]);
        pos[x] = v;
        pos[y] = u;

        for (int k : ks) addK(k);
    }

    void outputOne(string &out) const {
        out += "1\n\n";
    }

    void outputTwo(string &out, int k) const {
        out += "2\n";
        appendInt(out, k);
        out.push_back('\n');
    }

    void outputZero(string &out) const {
        out += "0\n";
    }

    void answer(string &out) const {
        if (powerOfTwo || good(a[1], a[n])) {
            outputOne(out);
            return;
        }

        int firstType = type(a[1]);

        // If there is an inner adjacent pair with type:
        // type(a1) -> type(an), it is a valid split.
        if (!trans[firstType].empty()) {
            outputTwo(out, *trans[firstType].begin());
            return;
        }

        // No such type transition exists.
        // Let h be the high endpoint, h = P + z.
        int highEndpoint = firstType ? a[1] : a[n];
        int z = highEndpoint - P;

        if (R >= 2) {
            // z and z^1 are two different low values compatible with highEndpoint.
            int c1 = z;
            int c2 = z ^ 1;

            int k;

            if (firstType == 1) {
                // a1 is high, an is low.
                // Interior order is low...low high...high.
                // Low positions are 2..P.
                // We need a compatible low value not at position P.
                int val = (pos[c1] != P ? c1 : c2);
                k = pos[val];
            } else {
                // a1 is low, an is high.
                // Interior order is high...high low...low.
                // Low positions start at R+1.
                // We need a compatible low value not at position R+1.
                int val = (pos[c1] != R + 1 ? c1 : c2);
                k = pos[val] - 1;
            }

            outputTwo(out, k);
            return;
        }

        // R == 1.
        // The only low value compatible with the high endpoint is 0.
        int pos0 = pos[0];

        if (firstType == 1) {
            // a1 high, an low.
            // Need 0 not to be the last low position P.
            if (pos0 == P) {
                outputZero(out);
            } else {
                outputTwo(out, pos0);
            }
        } else {
            // a1 low, an high.
            // Need 0 not to be the first low position R+1 = 2.
            if (pos0 == R + 1) {
                outputZero(out);
            } else {
                outputTwo(out, pos0 - 1);
            }
        }
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;

    string out;
    out.reserve(1 << 22);

    while (T--) {
        int n, q;
        cin >> n >> q;

        vector<int> arr(n + 1);
        for (int i = 1; i <= n; i++) {
            cin >> arr[i];
        }

        Solver solver;
        solver.init(n, q, arr);

        solver.answer(out);

        for (int i = 0; i < q; i++) {
            int u, v;
            cin >> u >> v;

            solver.doSwap(u, v);
            solver.answer(out);
        }
    }

    cout << out;
    return 0;
}