Submission #927843

#TimeUsernameProblemLanguageResultExecution timeMemory
927843minhnhatnoeAlice, Bob, and Circuit (APIO23_abc)C++17
54 / 100
66 ms15256 KiB
#include "abc.h" #include <bits/stdc++.h> using namespace std; enum OP { 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 }; namespace ab{ int v[5]; int ctoi(const char *a){ int len = strlen(a); int x = 0; for (int i=0; i<len; i++){ x = x * 26 + a[i] - 'a'; } return x + v[len]; } struct __init__{ __init__(){ v[1] = 0; v[2] = v[1] + 26; v[3] = v[2] + 26 * 26; v[4] = v[3] + 26 * 26 * 26; } } __init__; } // Alice int // returns la alice( /* in */ const int n, /* in */ const char names[][5], /* in */ const unsigned short numbers[], /* out */ bool outputs_alice[]) { vector<pair<int, unsigned short>> a; for (int i=0; i<n; i++){ a.emplace_back(ab::ctoi(names[i]), numbers[i]); } sort(a.begin(), a.end()); int ptr = 0; for (int i=0; i<n; i++){ for (int k=0; k<16; k++){ outputs_alice[ptr++] = a[i].second & (1 << k); } } for (int i=0; i<n; i++){ int v = ab::ctoi(names[i]); int pos = lower_bound(a.begin(), a.end(), pair<int, unsigned short>(v, 0)) - a.begin(); assert(a[pos].first == v); for (int k=0; k<16; k++){ outputs_alice[ptr++] = pos & (1 << k); } } return ptr; } // Bob int // returns lb bob( /* in */ const int m, /* in */ const char senders[][5], /* in */ const char recipients[][5], /* out */ bool outputs_bob[]) { vector<int> pp; for (int i=0; i<m; i++){ pp.emplace_back(ab::ctoi(senders[i])); pp.emplace_back(ab::ctoi(recipients[i])); } sort(pp.begin(), pp.end()); pp.resize(unique(pp.begin(), pp.end()) - pp.begin()); vector<vector<int>> g(pp.size(), vector<int> (pp.size())); for (int i=0; i<m; i++){ int x = ab::ctoi(senders[i]); x = lower_bound(pp.begin(), pp.end(), x) - pp.begin(); int y = ab::ctoi(recipients[i]); y = lower_bound(pp.begin(), pp.end(), y) - pp.begin(); g[x][y]++; } int ptr = 0; for (int i=0; i<pp.size(); i++){ for (int j=0; j<pp.size(); j++){ outputs_bob[ptr++] = g[i][j]; } } return ptr; } namespace circuit_ns{ struct bit{ int v = 0; }; bit zero, one; struct bit_construct{ OP p; bit x, y; }; vector<bit_construct> a; bit create_gate(OP p, bit x, bit y){ assert(x.v != -1 && y.v != -1); a.push_back({p, x, y}); return bit{int(a.size()-1)}; }; #define DEF_OP(op, name) bit operator op (const bit &a, const bit &b){return create_gate(name, a, b);} DEF_OP(&, OP_AND) DEF_OP(|, OP_OR) DEF_OP(^, OP_XOR) DEF_OP(==, OP_EQUAL) #undef DEF_OP struct nbr{ bit s[16]; nbr(){ memset(s, -1, sizeof s); } nbr(int spos){ for (int i=0; i<16; i++) s[i].v = spos + i; } void init_value(int v){ for (int i=0; i<16; i++){ if (v & (1 << i)) s[i] = one; else s[i] = zero; } } }; 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 three{-1}; ptr < 16; ptr++){ bit one = l.s[ptr], two = r.s[ptr]; assert(one.v != -1 && two.v != -1); if (three.v == -1){ result.s[ptr] = one ^ two; three = one & two; } else{ bit four = one ^ two; bit five = result.s[ptr] = four ^ three; bit six = one & two; bit seven = four & three; three = six | seven; } } return result; } nbr operator<<(const nbr &a, int b){ nbr result; copy(a.s, a.s + 16 - b, result.s + b); return result; } nbr operator&(const nbr &a, const bit &g){ nbr result; for (int i=0; i<16; i++){ if (a.s[i].v == -1) continue; result.s[i] = a.s[i] & g; } return result; } 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; } nbr operator|(const nbr &lhs, const nbr &rhs){ nbr result; for (int i=0; i<16; i++){ if (lhs.s[i].v == -1) result.s[i] = rhs.s[i]; else if (rhs.s[i].v == -1) result.s[i] = lhs.s[i]; else result.s[i] = lhs.s[i] | rhs.s[i]; } return result; } bit operator==(nbr lhs, nbr rhs){ bit result{-1}; for (int i=0; i<16; i++){ if (lhs.s[i].v == -1 && rhs.s[i].v == -1) continue; if (lhs.s[i].v == -1) lhs.s[i] = zero; if (rhs.s[i].v == -1) rhs.s[i] = zero; bit eq = (lhs.s[i] == rhs.s[i]); if (result.v == -1) result = eq; else result = result & eq; } return result; } void erase_deps(int la, int lb, vector<nbr> &results){ vector<int> act(a.size()); for (int i=0; i<la + lb; i++) act[i] = 1; for (const nbr &v: results){ for (bit x: v.s){ if (x.v == -1) x = zero; act[x.v] = 1; } } for (int i=a.size()-1; i>=la+lb; i--){ if (act[i] == 0) continue; assert(a[i].x.v < i && a[i].y.v < i); act[a[i].x.v] = act[a[i].y.v] = 1; } int cnt = 0; vector<bit_construct> s; for (int i=0; i<a.size(); i++){ if (act[i] == 0) continue; act[i] = cnt++; s.push_back({a[i].p, bit{act[a[i].x.v]}, bit{act[a[i].y.v]}}); } a = move(s); for (nbr &r: results){ for (bit &v: r.s) v.v = act[v.v]; } } void init(int la, int lb){ a.resize(la + lb); zero = create_gate(OP_ZERO, bit{0}, bit{0}); one = create_gate(OP_ONE, bit{0}, bit{0}); } int output(int la, int lb, int ops[], int opers[][2], int outputs[][16], vector<nbr> result){ erase_deps(la, lb, result); 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<result.size(); i++){ for (int j=0; j<16; j++){ outputs[i][j] = result[i].s[j].v; } } return a.size(); } int run(int la, int lb, int ops[], int opers[][2], int outputs[][16]){ init(la, lb); int n = la / 32, ptr = 0; vector<nbr> aweight(n); for (int i=0; i<n; i++){ aweight[i] = nbr(ptr); ptr += 16; } vector<nbr> aposi(n); for (int i=0; i<n; i++){ aposi[i] = nbr(ptr); ptr += 16; } assert(ptr == la); vector<vector<bit>> g(n, vector<bit> (n)); for (int i=0; i<n; i++){ for (int j=0; j<n; j++){ g[i][j].v = ptr++; } } assert(ptr == la + lb); vector<nbr> tresult(n); for (int i=0; i<n; i++){ for (int j=0; j<n; j++){ tresult[j] = tresult[j] + (aweight[i] & g[i][j]); } } vector<nbr> result(n); for (int i=0; i<n; i++){ for (int j=0; j<n; j++){ nbr jn; jn.init_value(j); result[i] = result[i] + (tresult[j] & (aposi[i] == jn)); } } return output(la, lb, ops, opers, outputs, result); } } // TODO: erase deps // 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::run(la, lb, operations, operands, outputs_circuit); }

Compilation message (stderr)

abc.cpp: In function 'int bob(int, const char (*)[5], const char (*)[5], bool*)':
abc.cpp:102:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  102 |     for (int i=0; i<pp.size(); i++){
      |                   ~^~~~~~~~~~
abc.cpp:103:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  103 |         for (int j=0; j<pp.size(); j++){
      |                       ~^~~~~~~~~~
abc.cpp: In constructor 'circuit_ns::nbr::nbr()':
abc.cpp:139:35: warning: 'void* memset(void*, int, size_t)' writing to an object of non-trivial type 'struct circuit_ns::bit'; use assignment instead [-Wclass-memaccess]
  139 |             memset(s, -1, sizeof s);
      |                                   ^
abc.cpp:111:12: note: 'struct circuit_ns::bit' declared here
  111 |     struct bit{
      |            ^~~
abc.cpp: In function 'circuit_ns::nbr circuit_ns::operator+(const circuit_ns::nbr&, const circuit_ns::nbr&)':
abc.cpp:171:21: warning: variable 'five' set but not used [-Wunused-but-set-variable]
  171 |                 bit five = result.s[ptr] = four ^ three;
      |                     ^~~~
abc.cpp: In function 'void circuit_ns::erase_deps(int, int, std::vector<circuit_ns::nbr>&)':
abc.cpp:262:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<circuit_ns::bit_construct>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  262 |         for (int i=0; i<a.size(); i++){
      |                       ~^~~~~~~~~
abc.cpp: In function 'int circuit_ns::output(int, int, int*, int (*)[2], int (*)[16], std::vector<circuit_ns::nbr>)':
abc.cpp:279:28: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<circuit_ns::bit_construct>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  279 |         for (int i=la+lb; i<a.size(); i++){
      |                           ~^~~~~~~~~
abc.cpp:284:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<circuit_ns::nbr>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  284 |         for (int i=0; i<result.size(); i++){
      |                       ~^~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...