Submission #1178925

#TimeUsernameProblemLanguageResultExecution timeMemory
1178925KanonBit Shift Registers (IOI21_registers)C++20
0 / 100
1 ms584 KiB
#include <bits/stdc++.h> #include "registers.h" using namespace std; const int b = 2000; const int m = 100; vector<bitset<b>> r(m); int cnt = 0; int so_far = 0; void Move(int t, int y) { r[t] = r[y]; so_far++; } int Store(vector<bool> v) { so_far++; int t = cnt++; assert(int(v.size()) == b); append_store(t, v); for (int i = 0; i < b; i++) r[t][i] = v[i]; return t; } int And(int x, int y) { so_far++; int t = cnt++; append_and(t, x, y); r[t] = r[x] & r[y]; return t; } int Or(int x, int y) { so_far++; int t = cnt++; append_or(t, x, y); r[t] = r[x] | r[y]; return t; } int Xor(int x, int y) { so_far++; int t = cnt++; append_xor(t, x, y); r[t] = r[x] ^ r[y]; return t; } int Not(int x) { so_far++; int t = cnt++; append_not(t, x); for (int i = 0; i < b; i++) r[t][i] = r[x][i] ? 0 : 1; return t; } int Shift_left(int x, int p) { so_far++; int t = cnt++; append_left(t, x, p); r[t] = r[x] << p; return t; } int Shift_right(int x, int p) { so_far++; int t = cnt++; append_right(t, x, p); r[t] = r[x] >> p; return t; } int Add(int x, int y) { so_far++; int t = cnt++; append_add(t, x, y); int carries = 0; for (int i = 0; i < b; i++) { int sum = r[x][i] + r[y][i] + carries; r[t][i] = sum % 2; carries = sum / 2; } return t; } struct Bitset { int id = -1; Bitset(int _id) : id(_id) {}; Bitset operator-() const { return Bitset(Not(id)); }; Bitset operator>>(int p) { return Bitset(Shift_right(id, p)); }; Bitset operator<<(int p) { return Bitset(Shift_left(id, p)); }; void operator=(const Bitset &a) { Move(id, a.id); }; }; Bitset operator+(const Bitset &lhs, const Bitset &rhs) { return Bitset(Add(lhs.id, rhs.id)) ;} Bitset operator^(const Bitset &lhs, const Bitset &rhs) { return Bitset(Xor(lhs.id, rhs.id)) ;} Bitset operator|(const Bitset &lhs, const Bitset &rhs) { return Bitset(Or(lhs.id, rhs.id)) ;} Bitset operator&(const Bitset &lhs, const Bitset &rhs) { return Bitset(And(lhs.id, rhs.id)) ;} Bitset Store(const function<bool(const int&)> &f) { vector<bool> bits(b); for (int i = 0; i < b; i++) bits[i] = f(i); return Bitset(Store(bits)); } void construct_instructions(int s, int n, int k, int q) { Bitset a = Bitset(0); cnt++; Bitset Full = Store([&](int i) { return true; }); Bitset One = Store([&](int i) { return i == 0; }); int reset_register = cnt; auto Lesser_greater = [&](Bitset Even_skipped_blocks, Bitset Odd_skipped_blocks, int total_blocks) { assert(total_blocks & 1); Bitset Full_even_indexes = Store([&](int i) { int block_id = i / k; if (block_id >= total_blocks) return false; if (block_id & 1) return false; return true; }); Bitset Header_remainder_even_blocks = Store([&](int i) { int block_id = i / k; if (block_id >= total_blocks + 1) return false; if (i % (2 * k) == k) return true; return false; }); Bitset Even_plus_full_minus_odd = Even_skipped_blocks + (Full_even_indexes ^ Odd_skipped_blocks); Bitset Greater_even_blocks_head = Even_plus_full_minus_odd & Header_remainder_even_blocks; Bitset Full_greater_even_blocks = Greater_even_blocks_head + (Full ^ Greater_even_blocks_head >> k) + One; Bitset Full_not_less_odd_blocks = Full_greater_even_blocks ^ Full_even_indexes; Bitset Greater_skipped = (Even_skipped_blocks & Full_greater_even_blocks) ^ (Odd_skipped_blocks & Full_not_less_odd_blocks); Bitset Lesser_skipped = Even_skipped_blocks ^ Odd_skipped_blocks ^ Greater_skipped; Bitset ret = Lesser_skipped ^ (Greater_skipped << k); return ret; }; auto E_O_switch = [&]() { Bitset Even_skipped_blocks = a & Store([&](int i) { if (i >= n * k) return false; int block_id = i / k; return block_id % 2 == 0; }); Bitset Odd_skipped_blocks = (a & Store([&](int i) { if (i >= n * k) return false; int block_id = i / k; return block_id % 2 == 1; })) >> k; int last_even_block_id = n - 1 - (n & 1 ^ 1); int last_odd_block_id = n - 1 - (n & 1); int total_block = last_even_block_id + 1; if (last_odd_block_id != total_block) Odd_skipped_blocks = Odd_skipped_blocks | Store([&](int i) { int L = (total_block - 1) * k, R = L + k - 1; return L <= i && i <= R; }); a = Lesser_greater(Even_skipped_blocks, Odd_skipped_blocks, total_block); if (last_odd_block_id != total_block) a = a ^ Store([&](int i) { int L = total_block * k + k, R = L + k - 1; return L <= i && i <= R; }); cnt = reset_register; }; auto O_E_switch = [&]() { if (n <= 2) return; Bitset Even_skipped_blocks = (a & Store([&](int i) { if (i >= n * k) return false; int block_id = i / k; return block_id % 2 == 0; })) >> (k << 1); Bitset Odd_skipped_blocks = (a & Store([&](int i) { if (i >= n * k) return false; int block_id = i / k; return block_id % 2 == 1; })) >> k; int last_even_block_id = n - 1 - (n & 1 ^ 1); int last_odd_block_id = n - 1 - (n & 1); int total_block = last_odd_block_id; if (last_even_block_id != total_block + 1) Even_skipped_blocks = Even_skipped_blocks | Store([&](int i) { int L = (total_block - 1) * k, R = L + k - 1; return L <= i && i <= R; }); Bitset first_block = a & Store([&](int i) { return i < k; }); a = Lesser_greater(Odd_skipped_blocks, Even_skipped_blocks, total_block) << k | first_block; if (last_odd_block_id != total_block) a = a ^ Store([&](int i) { int L = (total_block + 1) * k + k, R = L + k - 1; return L <= i && i <= R; }); cnt = reset_register; }; if (s == 1) { int beg = 0; int iter = n; while (iter--) { if (!beg & 1) { E_O_switch(); } else { O_E_switch(); } beg ^= 1; } assert(so_far <= q); } else { Bitset Full_even_indexes = Store([&](int i) { int block_id = i / k; if (block_id & 1) return false; return true; }); Bitset Header_remainder_even_blocks = Store([&](int i) { int block_id = i / k; if (i % (2 * k) == k) return true; return false; }); auto Lesser = [&](Bitset Even_skipped_blocks, Bitset Odd_skipped_blocks) { Bitset Even_plus_full_minus_odd = Even_skipped_blocks + (Full_even_indexes ^ Odd_skipped_blocks); Bitset Greater_even_blocks_head = Even_plus_full_minus_odd & Header_remainder_even_blocks; Bitset Full_greater_even_blocks = Greater_even_blocks_head + (Full ^ Greater_even_blocks_head >> k) + One; Bitset Full_not_less_odd_blocks = Full_greater_even_blocks ^ Full_even_indexes; Bitset Lesser_skipped = (Even_skipped_blocks & Full_not_less_odd_blocks) ^ (Odd_skipped_blocks & Full_greater_even_blocks); return Lesser_skipped; }; a = a | Store([&](int i) { return n * k <= i; }); Bitset Even_skipped_blocks = a & Full_even_indexes; Bitset Odd_skipped_blocks = (a & Full_even_indexes << k) >> k; Bitset Lesser_skipped = Lesser(Even_skipped_blocks, Odd_skipped_blocks); int Log = 1; while ((1 << Log) - 1 < n - 1) { Lesser_skipped = Lesser(Lesser_skipped, Lesser_skipped >> (k << Log)); Log++; } a = Lesser_skipped; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...