This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "abc.h"
#include <bits/stdc++.h>
using namespace std;
enum OPS
{
OP_ZERO, // f(OP_ZERO, x0, x1) = 0
OP_NOR, // f(OP_NOR, x0, x1) = !(x0 || x1)
OP_GREATER, // f(OP_GREATER, x0, x1) = (x0 > x1)
OP_NOT_X1, // f(OP_NOT_X1, x0, x1) = !x1
OP_LESS, // f(OP_LESS, x0, x1) = (x0 < x1)
OP_NOT_X0, // f(OP_NOT_X0, x0, x1) = !x0
OP_XOR, // f(OP_XOR, x0, x1) = (x0 ^ x1)
OP_NAND, // f(OP_NAND, x0, x1) = !(x0 && x1)
OP_AND, // f(OP_AND, x0, x1) = (x0 && x1)
OP_EQUAL, // f(OP_EQUAL, x0, x1) = (x0 == x1)
OP_X0, // f(OP_X0, x0, x1) = x0
OP_GEQ, // f(OP_GEQ, x0, x1) = (x0 >= x1)
OP_X1, // f(OP_X1, x0, x1) = x1
OP_LEQ, // f(OP_LEQ, x0, x1) = (x0 <= x1)
OP_OR, // f(OP_OR, x0, x1) = (x0 || x1)
OP_ONE, // f(OP_ONE, x0, x1) = 1
};
// Alice
int // returns la
alice(
/* in */ const int n,
/* in */ const char names[][5],
/* in */ const unsigned short numbers[],
/* out */ bool outputs_alice[])
{
int a = numbers[0];
for (int i=0; i<16; i++)
outputs_alice[i] = a & (1 << i);
return 16;
}
// Bob
int // returns lb
bob(
/* in */ const int m,
/* in */ const char senders[][5],
/* in */ const char recipients[][5],
/* out */ bool outputs_bob[])
{
for (int i=0; i<16; i++)
outputs_bob[i] = m & (1 << i);
return 16;
}
namespace circuit_ns{
struct bit_pos{
int v;
};
struct bit_gate{
OPS p;
bit_pos x, y;
};
vector<bit_gate> a;
bit_pos create_gate(OPS p, bit_pos x, bit_pos y){
assert(x.v != -1 && y.v != -1);
a.push_back({p, x, y});
return bit_pos{int(a.size()-1)};
};
struct nbr{
bit_pos s[16];
nbr(){
memset(s, -1, sizeof s);
}
friend nbr operator+(const nbr &l, const nbr &r){
nbr result;
int ptr = 0;
for (; ptr<16 && (l.s[ptr].v == -1 && r.s[ptr].v == -1); ptr++){
result.s[ptr].v = -1;
}
for (; ptr<16 && (l.s[ptr].v == -1 || r.s[ptr].v == -1); ptr++){
result.s[ptr] = (l.s[ptr].v != -1 ? l.s[ptr] : r.s[ptr]);
}
for (bit_pos three{-1}; ptr < 16; ptr++){
bit_pos one = l.s[ptr], two = r.s[ptr];
assert(one.v != -1 && two.v != -1);
if (three.v == -1){
result.s[ptr] = create_gate(OP_XOR, one, two);
three = create_gate(OP_AND, one, two);
}
else{
bit_pos four = create_gate(OP_XOR, one, two);
bit_pos five = result.s[ptr] = create_gate(OP_XOR, four, three);
bit_pos six = create_gate(OP_AND, one, two);
bit_pos seven = create_gate(OP_AND, four, three);
three = create_gate(OP_OR, six, seven);
}
}
return result;
}
friend nbr operator<<(const nbr &a, int b){
nbr result;
copy(a.s, a.s + 16 - b, result.s + b);
return result;
}
friend nbr operator&(const nbr &a, const bit_pos &g){
nbr result;
for (int i=0; i<16; i++){
if (a.s[i].v == -1) continue;
result.s[i] = create_gate(OP_AND, a.s[i], g);
}
return result;
}
friend nbr operator*(const nbr &lhs, const nbr &rhs){
int sizeab = a.size();
nbr ab;
{
nbr nb = rhs;
for (int i=0; i<16; i++){
if (lhs.s[i].v == -1) continue;
nbr anb = nb & lhs.s[i];
ab = ab + anb;
nb = nb << 1;
}
sizeab = a.size() - sizeab;
}
int sizeba = a.size();
nbr ba;
{
nbr na = lhs;
for (int i=0; i<16; i++){
if (rhs.s[i].v == -1) continue;
nbr ana = na & rhs.s[i];
ba = ba + ana;
na = na << 1;
}
sizeba = a.size() - sizeab;
}
if (sizeab <= sizeba) return ab;
else return ba;
}
};
int init(int la, int lb, int ops[], int opers[][2], int outputs[][16]){
a.resize(la + lb);
nbr x, y;
for (int i=0; i<16; i++) x.s[i].v = i, y.s[i].v = 16 + i;
nbr result = x * y;
bit_pos zero = create_gate(OP_ZERO, bit_pos{0}, bit_pos{0});
for (int i=la+lb; i<a.size(); i++){
ops[i] = a[i].p;
opers[i][0] = a[i].x.v;
opers[i][1] = a[i].y.v;
}
for (int i=0; i<16; i++){
outputs[0][i] = result.s[i].v;
if (outputs[0][i] == -1) outputs[0][i] = zero.v;
}
return a.size();
}
}
// Circuit
int // returns l
circuit(
/* in */ const int la,
/* in */ const int lb,
/* out */ int operations[],
/* out */ int operands[][2],
/* out */ int outputs_circuit[][16])
{
return circuit_ns::init(la, lb, operations, operands, outputs_circuit);
}
Compilation message (stderr)
abc.cpp: In function 'circuit_ns::nbr circuit_ns::operator+(const circuit_ns::nbr&, const circuit_ns::nbr&)':
abc.cpp:91:29: warning: variable 'five' set but not used [-Wunused-but-set-variable]
91 | bit_pos five = result.s[ptr] = create_gate(OP_XOR, four, three);
| ^~~~
abc.cpp: In function 'int circuit_ns::init(int, int, int*, int (*)[2], int (*)[16])':
abc.cpp:152:28: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<circuit_ns::bit_gate>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
152 | for (int i=la+lb; i<a.size(); i++){
| ~^~~~~~~~~
# | 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... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |