/* 略解: i & K が等しい整数を同じグループに分ける。 各グループの要素を昇順に並べた列を v とする。 |v| = s とし、s 以上の最小の 2 冪を m とする。 添字 i = m-s, ..., s-1 の要素について、 v[i] と v[m-1-i] をペアにする。 このとき、ペアの AND は必ずグループのキーと等しい。 残った先頭 m-s 個の要素について同じ操作を繰り返す。 全グループを処理すると、AND の OR は K になる。 ただし、K が N 以上の 2 冪のビットを含む場合は不可能。 計算量は O(N)。 */ #include using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N, K; cin >> N >> K; int lim = 1; while (lim < N) lim *= 2; if (K >= lim) { cout << "No\n"; return 0; } vector> G(N); for (int i = 0; i < N; i++) { G[i & K].push_back(i); } vector P, Q; for (auto &v : G) { while (!v.empty()) { int s = v.size(); int m = 1; while (m < s) m *= 2; for (int i = m - s; i < s; i++) { P.push_back(v[i]); Q.push_back(v[m - 1 - i]); } v.resize(m - s); } } cout << "Yes\n"; for (const auto &v : {P, Q}) { for (int i = 0; i < N; i++) { cout << v[i] << (i == N - 1 ? "\n" : " "); } } }