#include #include using namespace std; using ll = long long; // f+1ビットを64ビットブロックに分解したときのブロック数を計算 inline int getBlocks(int size) { return (size + 63) / 64; } // bits 配列を shiftVal ビット左にシフトした結果を返す vector shiftBits(const vector& bits, int shiftVal, int blocks) { vector res(blocks, 0ULL); int blockShift = shiftVal / 64; int bitShift = shiftVal % 64; for (int i = 0; i < blocks; i++) { if (bits[i] == 0) continue; int targetIndex = i + blockShift; if (targetIndex < blocks) { // シフトした後、下位側のシフト res[targetIndex] |= bits[i] << bitShift; } if (bitShift && targetIndex + 1 < blocks) { // 残りは次のブロックに繰り上がる部分 res[targetIndex + 1] |= bits[i] >> (64 - bitShift); } } return res; } // 3つのビット列の OR を取る vector orBits(const vector& A, const vector& B, const vector& C, int blocks) { vector res(blocks, 0ULL); for (int i = 0; i < blocks; i++) { res[i] = A[i] | B[i] | C[i]; } return res; } // 各ブロックのビットの立っている数をカウント ll countBits(const vector& bits) { ll cnt = 0; for (auto x : bits) cnt += __builtin_popcountll(x); return cnt; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); ll n, f; cin >> n >> f; vector a(n), b(n), c(n); for (ll i = 0; i < n; i++) { cin >> a[i]; } for (ll i = 0; i < n; i++) { cin >> b[i]; } for (ll i = 0; i < n; i++) { cin >> c[i]; } // 必要なビット数は f+1 に限定 int size = f + 1; int blocks = getBlocks(size); // 初期状態: 0番目だけ立っている vector cur(blocks, 0ULL); cur[0] = 1ULL; // 各操作ごとにシフト & OR を行い、状態のビット数を出力 for (ll i = 0; i < n; i++) { vector sA = shiftBits(cur, a[i], blocks); vector sB = shiftBits(cur, b[i], blocks); vector sC = shiftBits(cur, c[i], blocks); cur = orBits(sA, sB, sC, blocks); cout << countBits(cur) << "\n"; } return 0; }