Solution for LuoguP4246

#include <bits/stdc++.h>

using std::string, std::cin, std::cout;

const int N = 232323;

int g[N << 1];
int n;
struct Node {
    int a[4][4];
    int l, r;
    Node () {
        memset (a, 0, sizeof a);
        l = r = 0;
    }
    void init(int p) {
        l = r = p;
        a[0][1] = a[1][0] = a[2][3] = a[3][2] = 1;
        for (int i = 0; i < 4; i ++)
            for (int j = 0; j < 4; j ++)
                if (a[i][j] != 1 && i != j)
                    a[i][j] = g[n * 2 + p];
    }
} z[N << 2];

Node operator + (const Node &lhs, const Node &rhs) {
    Node res;
    res.l = lhs.l, res.r = rhs.r;
    res.a[0][1] = res.a[1][0] = lhs.a[0][1] && g[lhs.r] && rhs.a[0][1] || lhs.a[0][3] && g[lhs.r + n] && rhs.a[2][1];
    res.a[0][2] = res.a[2][0] = lhs.a[0][2] || lhs.a[0][1] && g[lhs.r] && rhs.a[0][2] && g[lhs.r + n] && lhs.a[3][2];
    res.a[0][3] = res.a[3][0] = lhs.a[0][1] && g[lhs.r] && rhs.a[0][3] || lhs.a[0][3] && g[lhs.r + n] && rhs.a[2][3];
    res.a[1][2] = res.a[2][1] = lhs.a[2][1] && g[lhs.r] && rhs.a[0][1] || lhs.a[2][3] && g[lhs.r + n] && rhs.a[2][1];
    res.a[1][3] = res.a[3][1] = rhs.a[1][3] || rhs.a[1][0] && g[lhs.r] && lhs.a[1][3] && g[lhs.r + n] && rhs.a[2][3];
    res.a[2][3] = res.a[3][2] = lhs.a[2][1] && g[lhs.r] && rhs.a[0][3] || lhs.a[2][3] && g[lhs.r + n] && rhs.a[2][3];
    res.a[0][0] = res.a[1][1] = res.a[2][2] = res.a[3][3] = 1;
    return res;
}

void build(int l, int r, int rt) {
    if (l == r)
        z[rt] = Node();
    else {
        int mid = l + r >> 1;
        build(l, mid, rt << 1), build(mid + 1, r, rt << 1 | 1);
        z[rt] = z[rt << 1] + z[rt << 1 | 1];
    }
}

void modify(int l, int r, int rt, int nowl, int nowr) {
    if (l == r)
        z[rt].init(l);
    else {
        int mid = l + r >> 1;
        if (nowr <= mid)
            modify(l, mid, rt << 1, nowl, nowr);
        else if (mid < nowl)
            modify(mid + 1, r, rt << 1 | 1, nowl, nowr);
        else {
            modify(l, mid, rt << 1, nowl, mid);
            modify(mid + 1, r, rt << 1 | 1, mid + 1, nowr);
        }
        z[rt] = z[rt << 1] + z[rt << 1 | 1];
    }
}

Node query(int l, int r, int rt, int x, int y) {
    if (l == x && r == y)
        return z[rt];
    int mid = l + r >> 1;
    if (y <= mid)
        return query(l, mid, rt << 1, x, y);
    if (mid < x)
        return query(mid + 1, r, rt << 1 | 1, x, y);
    return query(l, mid, rt << 1, x, mid) + query(mid + 1, r, rt << 1 | 1, mid + 1, y);
}

signed main() {
    cin >> n;
    // build(1, n, 1);
    string s;
    while (cin >> s) {
        if (s == "Exit")
            break;
        else if (s == "Open" || s == "Close") {
            int r1, c1, r2, c2;
            cin >> r1 >> c1 >> r2 >> c2;
            if (c1 > c2) {
                r1 ^= r2 ^= r1 ^= r2;
                c1 ^= c2 ^= c1 ^= c2;
            }
            int flag = 0;
            if (s == "Open")
                flag = 1;
            if (c1 == c2)
                g[(n << 1) + c1] = flag;
            else {
                if (r1 == 1)
                    g[c1] = flag;
                else
                    g[n + c1] = flag;
            }
            modify(1, n, 1, c1, c2);
        } else {
            int r1, r2, c1, c2;
            cin >> r1 >> c1 >> r2 >> c2;
            if (c1 > c2) {
                r1 ^= r2 ^= r1 ^= r2;
                c1 ^= c2 ^= c1 ^= c2;
            }
            Node ans = query(1, n, 1, c1, c2);
            Node L = query(1, n, 1, 1, c1), R = query(1, n, 1, c2, n);
            int _1 = (r1 - 1) << 1, _2 = (r2 << 1) - 1;
            if (ans.a[_1][_2] || ans.a[_1 ^ 2][_2] && L.a[1][3] || ans.a[_1][_2 ^ 2] && R.a[0][2] || ans.a[_1 ^ 2][_2 ^ 2] && L.a[1][3] && R.a[0][2])
                puts("Y");
            else
                puts("N");
        }
    }
    return 0;
}