Submission #821386

#TimeUsernameProblemLanguageResultExecution timeMemory
821386PixelCatBit Shift Registers (IOI21_registers)C++17
89 / 100
3 ms1044 KiB
#include "registers.h" #ifdef NYAOWO #include "grader.cpp" #endif #include <bits/stdc++.h> #define For(i, a, b) for(int i = a; i <= b; i++) #define Forr(i, a, b) for(int i = a; i >= b; i--) #define F first #define S second #define sz(x) ((int)x.size()) #define all(x) x.begin(), x.end() #define eb emplace_back // #define int LL using namespace std; using i32 = int32_t; using LL = long long; using pii = pair<int, int>; // #define DEBUG #ifdef DEBUG #define PRINT(x) append_print(x) #else #define PRINT(x) #endif /* function signatures: void append_move(int t, int x) void append_store(int t, std::vector<bool> v) void append_and(int t, int x, int y) void append_or(int t, int x, int y) void append_xor(int t, int x, int y) void append_not(int t, int x) void append_left(int t, int x, int p) void append_right(int t, int x, int p) void append_add(int t, int x, int y) void append_print(int t) registers: 0 input/output 1 input/output (shifted right for k bits) 2 mask for useful segments (every other numbers) 3 mask for first bits of every useful segments 4 (m[0] ^ m[1]) & m[2] (XORs of adjacent numbers) 5 hi-bit of XORs of adjacent numbers 6 m[0] & m[5] (should this pair be swapped?) 7 'expanded' m[6] 8 m[7] & m[4] (swapping key for every pair of numbers) */ void make_sorter(int n, int k) { auto expand_right = [&](int r, int cnt) { int j = 1; while(j < cnt) { int j2 = min(j * 2, cnt) - j; append_right(49, r, j2); append_or(r, r, 49); j += j2; } }; // s = 0 or 1 auto make_masks = [&](int s) { vector<bool> m2(2000, 0); vector<bool> m3(2000, 0); for(int i = s; i < n - 1; i += 2) { m3[i * k] = 1; For(j, 0, k - 1) m2[i * k + j] = 1; } append_store(2, m2); append_store(3, m3); }; int parity = 1; For(_, 0, n) { parity = 1 - parity; make_masks(parity); append_right(1, 0, k); append_xor(4, 0, 1); append_and(4, 4, 2); // 5 append_move(5, 4); expand_right(5, k); append_and(5, 5, 2); append_add(5, 5, 3); append_right(5, 5, 1); // 12 append_and(6, 0, 5); append_left(7, 6, k - 1); expand_right(7, k * 2 - 1); // 12 append_and(8, 7, 4); append_xor(0, 0, 8); append_left(8, 8, k); append_xor(0, 0, 8); // 4 } } void make_min(int n, int k) { auto make_masks = [&](int i) { vector<bool> m_one(2000, 0), m_all(2000, 0), m_negall(2000, 1); m_one[i] = 1; for(int j = i; j < n * k; j += k) { m_all[j] = 1; m_negall[j] = 0; } For(j, 0, i - 1) m_negall[j] = 0; m_negall[i] = 1; append_store(2, m_one); append_store(3, m_all); append_store(4, m_negall); }; Forr(i, k - 1, 0) { make_masks(i); // = 3 operations // extract all ppl append_and(5, 0, 3); append_add(6, 4, 5); append_right(8, 6, 1000); append_not(7, 8); // = 7 operations // update answer append_and(2, 2, 7); append_or(1, 1, 2); // = 9 operations if(!i) break; // kill bad guys append_and(5, 5, 8); append_or(9, 5, 9); append_right(9, 9, 1); append_or(0, 0, 9); } append_move(0, 1); } void construct_instructions(int s, int n, int k, int q) { if(s == 1) make_sorter(n, k); else make_min(n, k); } /* 0 2 1 1000 0 0 0 1 1 0 1 1 -1 move 1 0 right 1 1 1 and 0 0 1 0 0 0 1 1 2 1 1000 0 0 0 1 1 0 1 1 -1 move 1 0 right 1 1 1 and 2 0 1 or 3 0 1 left 3 3 1 or 0 2 3 0 0 0 1 0 1 1 1 */
#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...