Submission #438291

#TimeUsernameProblemLanguageResultExecution timeMemory
438291CyanForcesBit Shift Registers (IOI21_registers)C++17
22 / 100
1 ms460 KiB
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for(int i = a; i < (b); ++i) #define trav(a, x) for(auto& a : x) #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() typedef long long ll; typedef pair<int, int> pii; typedef vector<int> vi; #include "registers.h" int s, n, k, q; int ops = 0; vector<bool> negOne(2000); vector<bool> signBit(2000); vector<bool> oneNum(2000); const int negOneIndex = 99; const int signBitIndex = 98; const int oneNumIndex = 97; const int workRegister = 96; int bit_len; void spread() { //append_print(0); // vector<bool> takeFirst(2000), takeSecond(2000); rep(i,0,2000) { int temp = (i / (k)) % 2; if (temp == 0) takeFirst[i] = 1; else takeSecond[i] = 1; } append_store(50, takeFirst); ops++; append_store(51, takeSecond); append_and(1, 0, 50); append_and(0, 0, 51); append_left(0, 0, (n-(n%2==0))*k); append_xor(1,0,1); //for(int i = 0; i < n; i++) { // append_and(workRegister, 0, oneNumIndex); // ops++; // if (i != n-1) { // append_left(oneNumIndex, oneNumIndex, bit_len); // ops++; // append_left(0, 0, k); // ops++; // } // append_or(1, 1, workRegister); // ops++; //} append_print(1); } void divide() { int leftNumbers = (n+1) / 2; //append_move(2, 1); ops++; append_right(2, 1, leftNumbers * (bit_len)); ops++; if(n % 2 == 1) { vector<bool> tempExtra(2000); rep(i,0,2000) { tempExtra[i] = (n-leftNumbers)*(bit_len) <= i && i < (n-leftNumbers+1)*(bit_len)-1; } append_store(3, tempExtra); ops++; append_or(2, 2, 3); ops++; } } void spreadSigns(int d) { ops++; append_right(workRegister, 0, d); ops++; append_or(0, 0, workRegister); ops++; } void combine() { ops++; append_add(0, negOneIndex, 2); // b-1 ops++; append_not(0, 0); // !(b-1) ops++; append_add(0, 0, 1); // a-b ops++; append_and(0, 0, signBitIndex); ops++; //rep(_,0,k+1) spreadSigns(1); int curr = 1; while(curr*2 < bit_len) { spreadSigns(curr); curr *= 2; } if (bit_len != curr) spreadSigns(bit_len - curr); append_not(workRegister, 0); ops++; // registry 0 contains zeros if a >= b, else 1 // => registry 0 contains a >= b // => workRegister contains a < b append_and(0, 0, 2); ops++; append_and(workRegister, workRegister, 1); ops++; //append_xor(1, 1, 2); // register 0 = xor(a, b) ops++; append_xor(1, 0, workRegister); ops++; // register 2 = max(a, b) //append_xor(1, 1, 2); ops++; } void print() { //rep(i,0,3) append_print(i); } void findMin() { spread(); //return; while(n > 1) { //print(); divide(); //print(); combine(); //print(); n = (n+1) / 2; } //print(); append_move(0, 1); ops++; } void unspread() { vector<bool> empty(2000); append_store(0, empty); int shiftAmount = n-1; for(int i = n-1; i >= 0; i--) { cerr << "i = " << i << endl; cerr << "ops = " << ops << endl; append_and(workRegister, 1, oneNumIndex); ops++; append_right(workRegister, workRegister, 2*i); ops++; append_right(oneNumIndex, oneNumIndex, bit_len); ops++; if (shiftAmount > 0) { append_right(workRegister, workRegister, shiftAmount * k); } else { append_left(workRegister, workRegister, -shiftAmount * k); } shiftAmount -= 2; append_or(0, 0, workRegister); ops++; } //append_store(oneNumIndex, oneNum); //append_store(1, empty); //spread(); //print(); } void stupidSort() { spread(); vector<bool> tempExtra(2000); rep(i,0,2000) { tempExtra[i] = i < k; } append_store(75, tempExtra); ops++; vector<bool> takeFirst(2000), takeSecond(2000); rep(i,0,2000) { int temp = (i / (bit_len)) % 2; if (temp == 0) takeFirst[i] = 1; else takeSecond[i] = 1; } append_store(50, takeFirst); ops++; append_store(51, takeSecond); ops++; cerr << "n = " << n << endl; print(); rep(i,0,n+3) { print(); cerr << "i = " << i << ", ops = " << ops << endl; append_move(2, 1); ops++; append_left(2, 2, bit_len); ops++; append_xor(2, 2, 75); ops++; combine(); print(); cerr << "i = " << i << ", ops = " << ops << endl; if (i % 2 == 0) { append_and(1, 1, 50); ops++; append_and(2, 2, 50); ops++; append_right(2, 2, bit_len); ops++; } else { append_and(1, 1, 51); ops++; append_and(2, 2, 51); ops++; append_right(2, 2, bit_len); ops++; } print(); append_or(1, 1, 2); ops++; append_print(52); } unspread(); } void construct_instructions(int _s, int _n, int _k, int _q) { s = _s; n = _n; k = _k; q = _q; bit_len = 2*k; int a = 0; int b = bit_len; while(b < 2000) { for(int j = a; j < b; j++) negOne[j] = j != b-1; a = b; b += bit_len; } for(int i = 0; i < 2000; i++) { signBit[i] = i % (bit_len) == bit_len-1; oneNum[i] = i < k; } append_store(negOneIndex, negOne); ops++; append_store(signBitIndex, signBit); ops++; //append_store(oneNumIndex, oneNum); ops++; if (s == 0) { findMin(); } else { stupidSort(); } assert(ops <= q); }
#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...