이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <assert.h>
#include "registers.h"
#define NUM_BITS 2000
static inline int ulong(int n) {
int l = 0;
while((1 << l) < n) l++;
return l;
}
void calc_min(int n, int k) {
//Fill rest of inputs with 1s
{
std::vector<bool> r(NUM_BITS);
for(int b = 0; b < NUM_BITS; b++) r[b] = (b >= n*k);
append_store(1, r);
append_or(0, 0, 1);
}
//Register plane algorithm
for(int i = 0; i < ulong(n); i++) {
//Split registers into two planes
append_move(1, 0);
append_right(1, 1, k << i);
//Calculate comparsion-add operands
append_xor(2, 0, 1);
append_and(3, 2, 0);
append_and(4, 2, 1);
append_not(4, 4);
//Mask operands
std::vector<bool> m(NUM_BITS);
for(int b = 0; b < NUM_BITS; b++) m[b] = (((b/k) % (1 << (i+1))) == 0);
append_store(5, m);
append_and(3, 3, 5);
append_and(4, 4, 5);
//Calculate comparison masks (0 if a is bigger)
append_add(3, 3, 4);
append_right(3, 3, k);
append_and(3, 3, 5);
append_add(3, 3, 5);
append_and(3, 3, 5);
//Update planes
append_and(0, 0, 3);
append_not(3, 3);
append_and(1, 1, 3);
append_or(0, 0, 1);
}
}
void bitonic_sort(int n, int k, int l) {
//Create flip mask
//If a bit is one, that means the bit has to be smaller in b, else in a
{
std::vector<bool> fm(NUM_BITS);
for(int b = 0; b < NUM_BITS; b++) fm[b] = (b / ((k+1) << (l+1))) % 2;
append_store(95, fm);
append_not(96, 95);
}
//Iterations of the sorting network
for(int p = l; p >= 0; p--) {
//Split registers into planes
append_move(1, 0);
append_right(1, 1, (k+1) << p);
//Calculate comparsion-add operands
append_xor(2, 0, 1);
append_and(3, 2, 0);
append_xor(3, 3, 95);
append_and(4, 2, 1);
append_xor(4, 4, 96);
//Mask operands
append_and(3, 3, 97);
append_and(4, 4, 97);
//Calculate comparison masks (0 if we should swap)
append_add(3, 3, 4);
append_and(3, 3, 98);
append_right(3, 3, k);
append_add(3, 3, 97);
append_and(3, 3, 97);
{
std::vector<bool> m(NUM_BITS);
for(int b = 0; b < NUM_BITS; b++) {
m[b] = (b % (k+1)) < k && ((b / ((k+1) << p)) % 2) == 0;
}
append_store(4, m);
append_and(3, 3, 4);
}
append_not(4, 3);
//Swap part 1
append_move(2, 0);
append_and(0, 0, 4);
append_and(1, 1, 3);
append_or(0, 0, 1);
//Update masks
append_left(2, 2, (k+1) << p);
append_left(3, 3, (k+1) << p);
append_left(4, 4, (k+1) << p);
{
std::vector<bool> m(NUM_BITS);
for(int b = 0; b < NUM_BITS; b++) m[b] = (b < ((k+1) << p));
append_store(5, m);
append_or(4, 4, 5);
}
//Swap part 2
append_and(0, 0, 4);
append_and(2, 2, 3);
append_or(0, 0, 2);
}
}
void sort_array(int n, int k) {
//Create input mask
{
std::vector<bool> m(NUM_BITS);
for(int b = 0; b < NUM_BITS; b++) m[b] = (b % (k+1)) < k;
append_store(97, m);
append_not(98, 97);
for(int b = 0; b < NUM_BITS; b++) m[b] = b < k;
append_store(99, m);
}
//Insert carry-catcher filler
for(int i = 0; i < n; i++) {
append_left(1, 1, k+1);
append_move(2, 0);
append_and(2, 2, 99);
append_or(1, 1, 2);
append_right(0, 0, k);
}
append_move(0, 1);
//Bitonic sorting network
for(int i = 0; i < ulong(n); i++) bitonic_sort(n, k, i);
//Remove carry-catcher filler
//The array has to be sorted backwards
for(int i = 0; i < n; i++) {
append_left(1, 1, k);
append_move(2, 0);
append_and(2, 2, 99);
append_or(1, 1, 2);
append_right(0, 0, k+1);
}
append_move(0, 1);
}
void construct_instructions(int s, int n, int k, int q) {
if(s == 0) calc_min(n, k);
else if(s == 1) sort_array(n, k);
else assert(false);
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |