This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
const int maxW = 13;
typedef bitset<1 << maxW> bs;
typedef vector<bs> vbs;
typedef vector<vbs> vvbs;
int W, H, K;
map<int, int> blocked;
vbs mod;
vi group;
vi degin, degout;
vvi adj;
bs dp[2];
vvbs lift;
void dfs(int idx, int base, int next, set<int> &nextdp)
{
    if (idx == W)
    {
        nextdp.insert(next);
        return;
    }
    if (base & (1 << idx))
        dfs(idx + 1, base, next, nextdp);
    else
    {
        // _X my pos: 1 << idx
        // TT
        // _T
        if (idx < W - 1 && ((3 << idx) & next) == 0)
            dfs(idx + 1, base | (1 << idx), next | (3 << idx), nextdp);
        // _TT
        // _T_
        if (idx > 0 && ((3 << (idx - 1)) & next) == 0)
            dfs(idx + 1, base | (1 << idx), next | (3 << (idx - 1)), nextdp);
        // T_
        // TT
        if (idx < W - 1 && (base & (3 << idx)) == 0 && (next & (2 << idx)) == 0)
            dfs(idx + 2, base | (3 << idx), next | (2 << idx), nextdp);
        // _T
        // TT
        if (idx < W - 1 && (base & (3 << idx)) == 0 && (next & (1 << idx)) == 0)
            dfs(idx + 2, base | (3 << idx), next | (1 << idx), nextdp);
    }
}
void step(bs &base, int block = 0)
{
    bs re = 0;
    for (int j = 0; j < 1 << W; ++j)
    {
        if (!base[j])
            continue;
        if (j & block)
            continue;
        for (int u : adj[j | block])
            re[u] = 1;
    }
    swap(base, re);
}
void mul(bs &base, int liftidx, bs &re, int block = 0)
{
    re = 0;
    for (int j = 0; j < 1 << W; ++j)
    {
        if (!base[j])
            continue;
        if (j & block)
            continue;
        re |= lift[liftidx][j | block];
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> W >> H >> K;
    for (int k = 0, x, y; k < K; ++k)
    {
        cin >> x >> y;
        --x, --y;
        blocked[y] = blocked[y] | (1 << x);
    }
    degin.assign(1 << W, 0), degout.assign(1 << W, 0);
    adj.resize(1 << W);
    for (int i = 0; i < 1 << W; ++i)
    {
        set<int> tmp;
        dfs(0, i, 0, tmp);
        degout[i] = sz(tmp);
        for (int u : tmp)
            adj[i].push_back(u), ++degin[u];
    }
    if (W <= 3)
    {
        lift.assign(ceil(log2(H) + 1), vbs(1 << W));
        for (int i = 0; i < 1 << W; ++i)
            for (int j : adj[i])
                lift[0][i][j] = 1;
        for (int j = 1; j < sz(lift); ++j)
            for (int i = 0; i < 1 << W; ++i)
                mul(lift[j - 1][i], j - 1, lift[j][i]);
        if (false)
        {
            dp[0] = 0;
            dp[0][0] = true;
            for (int i = 0; i < H; ++i)
            {
                int ii = i & 1;
                int ni = ii ^ 1;
                dp[ni] = 0;
                mul(dp[ii], 0, dp[ni], blocked[i]);
            }
            if (dp[H & 1][0])
                cout << "YES\n";
            else
                cout << "NO\n";
        }
        else
        {
            bs start = 0, tmp;
            start[0] = 1;
            blocked[H - 1] = blocked[H - 1] | 0;
            int h = 0;
            for (pii p : blocked)
            {
                for (int j = sz(lift) - 1; j >= 0; --j)
                {
                    if (p.first - h >= (1 << j))
                    {
                        h += (1 << j);
                        mul(start, j, tmp);
                        swap(start, tmp);
                    }
                }
                mul(start, 0, tmp, p.second);
                swap(start, tmp);
                ++h;
            }
            if (start[0])
                cout << "YES\n";
            else
                cout << "NO\n";
        }
    }
    else
    {
        group.assign(1 << W, -1);
        mod.assign(3, 0);
        if (W % 3 == 0)
        {
            int idx = 0;
            for (int i = 0; i < 1 << W; ++i)
            {
                if (group[i] != -1 || degout[i] == 0)
                    continue;
                bs start = 0;
                start[i] = 1;
                for (int j = 0; j < 12; ++j)
                    step(start);
                if (degin[i] == 0)
                {
                    int j = 0;
                    while (!start[j])
                        ++j;
                    group[i] = group[j];
                    continue;
                }
                mod[idx] = start;
                for (int j = 0; j < (1 << W); ++j)
                    if (start[j])
                        group[j] = idx;
                ++idx;
            }
            assert(idx == 3);
        }
        else
        {
            bs start = 0;
            start[0] = 1;
            for (int j = 0; j < 12; ++j)
                step(start);
            for (int idx = 0; idx < 3; ++idx)
            {
                for (int i = 0; i < 1 << W; ++i)
                    if (start[i])
                        group[i] = idx;
                mod[idx] = start;
                step(start);
            }
        }
        bs start = 0;
        start[0] = 1;
        blocked[H - 1] = blocked[H - 1] | 0;
        int h = 0;
        for (pii p : blocked)
        {
            int delta = p.first - h;
            if (delta >= 11)
            {
                set<int> G;
                if (W % 3 == 0)
                {
                    for (int i = 0; i < 1 << W; ++i)
                        if (start[i])
                            G.insert(group[i]);
                }
                else
                {
                    for (int i = 0; i < 1 << W; ++i)
                        if (start[i])
                            G.insert((group[i] + delta) % 3);
                }
                start = 0;
                for (int g : G)
                    start |= mod[g];
                h = p.first;
            }
            else
            {
                for (; h < p.first; ++h)
                    step(start);
            }
            step(start, p.second);
            ++h;
        }
        if (start[0])
            cout << "YES\n";
        else
            cout << "NO\n";
    }
    return 0;
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |