(UPD: 2024-12-04 14:48 UTC) Judge is not working due to Cloudflare incident. (URL) We can do nothing about it, sorry. After the incident is resolved, we will grade all submissions.

Submission #874579

#TimeUsernameProblemLanguageResultExecution timeMemory
874579StickfishAlice, Bob, and Circuit (APIO23_abc)C++17
66 / 100
124 ms65020 KiB
#include "abc.h" #include <algorithm> #include <iostream> #include <vector> using namespace std; // you may find the definitions useful const int OP_ZERO = 0; // f(OP_ZERO, x0, x1) = 0 const int OP_NOR = 1; // f(OP_NOR, x0, x1) = !(x0 || x1) const int OP_GREATER = 2; // f(OP_GREATER, x0, x1) = (x0 > x1) const int OP_NOT_X1 = 3; // f(OP_NOT_X1, x0, x1) = !x1 const int OP_LESS = 4; // f(OP_LESS, x0, x1) = (x0 < x1) const int OP_NOT_X0 = 5; // f(OP_NOT_X0, x0, x1) = !x0 const int OP_XOR = 6; // f(OP_XOR, x0, x1) = (x0 ^ x1) const int OP_NAND = 7; // f(OP_NAND, x0, x1) = !(x0 && x1) const int OP_AND = 8; // f(OP_AND, x0, x1) = (x0 && x1) const int OP_EQUAL = 9; // f(OP_EQUAL, x0, x1) = (x0 == x1) const int OP_X0 = 10; // f(OP_X0, x0, x1) = x0 const int OP_GEQ = 11; // f(OP_GEQ, x0, x1) = (x0 >= x1) const int OP_X1 = 12; // f(OP_X1, x0, x1) = x1 const int OP_LEQ = 13; // f(OP_LEQ, x0, x1) = (x0 <= x1) const int OP_OR = 14; // f(OP_OR, x0, x1) = (x0 || x1) const int OP_ONE = 15; // f(OP_ONE, x0, x1) = 1 void write_kbit(bool* arr, int k, int i, int x) { for (int t = 0; t < k; ++t) { arr[i + t] = x & (1 << t); } } string to_string(const char s[5]) { string ans; for (int i = 0; i < 5; ++i) { if (s[i] == '\0') break; ans.push_back(s[i]); } return ans; } // 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<string, int>> nms(n); for (int i = 0; i < n; ++i) { nms[i] = {to_string(names[i]), i}; } sort(nms.begin(), nms.end()); for (int i = 0; i < n; ++i) { write_kbit(outputs_alice, 16, 16 * i, numbers[nms[i].second]); } for (int i = 0; i < n; ++i) { write_kbit(outputs_alice, 5, 16 * n + 5 * i, nms[i].second); } return 21 * n; } // Bob int // returns lb bob( /* in */ const int m, /* in */ const char senders[][5], /* in */ const char recipients[][5], /* out */ bool outputs_bob[] ) { vector<pair<string, string>> edges(m); for (int i = 0; i < m; ++i) { edges[i] = {to_string(senders[i]), to_string(recipients[i])}; } vector<string> names; for (int i = 0; i < m; ++i) { names.push_back(edges[i].first); names.push_back(edges[i].second); } sort(names.begin(), names.end()); names.resize(unique(names.begin(), names.end()) - names.begin()); int n = names.size(); vector<vector<int>> edg(n, vector<int>(n, 0)); for (auto [s, r] : edges) { int si = lower_bound(names.begin(), names.end(), s) - names.begin(); int ri = lower_bound(names.begin(), names.end(), r) - names.begin(); ++edg[si][ri]; } for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { write_kbit(outputs_bob, 16, 16 * (i * n + j), edg[i][j]); } } return 16 * n * n; } int siz = 0; int* opt; int (*opr)[2]; inline void new_op(int a, int b, int op_type) { opt[siz] = op_type; opr[siz][0] = a; opr[siz][1] = b; ++siz; } int alg_sum(int a, int b, int k) { vector<int> digs(k); digs[0] = siz; new_op(a, b, OP_XOR); int conv = siz; new_op(a, b, OP_AND); for (int i = 1; i < k; ++i) { new_op(a + i, b + i, OP_XOR); new_op(siz - 1, conv, OP_XOR); digs[i] = siz - 1; int cache = siz; new_op(a + i, b + i, OP_OR); // cache new_op(conv, cache, OP_AND); // cache + 1 new_op(a + i, b + i, OP_AND); // cache + 2 new_op(cache + 1, cache + 2, OP_OR); conv = siz - 1; } int ans = siz; for (int i = 0; i < k; ++i) new_op(digs[i], digs[i], OP_AND); return ans; } int alg_multdig(int a, int cond, int k) { int ans = siz; for (int i = 0; i < k; ++i) { new_op(a + i, cond, OP_AND); } return ans; } int alg_multndig(int a, int cond, int k) { int ans = siz; for (int i = 0; i < k; ++i) { new_op(a + i, cond, OP_GREATER); } return ans; } int alg_inv(int a, int k) { int ans = siz; for (int i = 0; i < k; ++i) { new_op(a + i, a + i, OP_NOT_X0); } int add = siz; new_op(0, 0, OP_ONE); for (int i = 1; i < k; ++i) { new_op(0, 0, OP_ZERO); } return alg_sum(ans, add, k); } int alg_mult(int a, int b, int k) { int ans = siz; for (int i = 0; i < k; ++i) new_op(0, 0, OP_ZERO); for (int i = 0; i < k; ++i) { int val = siz; for (int j = 0; j < k; ++j) { if (j < i) new_op(0, 0, OP_ZERO); else new_op(b + i, a + j - i, OP_AND); } ans = alg_sum(ans, val, k); } return ans; } int alg_gr(int a, int b, int k) { int ans = siz; new_op(0, 0, OP_ZERO); int alleq = siz; new_op(0, 0, OP_ONE); for (int i = k - 1; i >= 0; --i) { new_op(a + i, b + i, OP_GREATER); new_op(siz - 1, alleq, OP_AND); new_op(siz - 1, ans, OP_OR); ans = siz - 1; new_op(a + i, b + i, OP_EQUAL); new_op(siz - 1, alleq, OP_AND); alleq = siz - 1; } return ans; } pair<int, int> swap_if(int a, int b, int cond, int k) { int sm = alg_sum(a, b, k); int ac = alg_inv(alg_multdig(a, cond, k), k); int anc = alg_inv(alg_multndig(a, cond, k), k); int bc = alg_inv(alg_multdig(b, cond, k), k); int bnc = alg_inv(alg_multndig(b, cond, k), k); // newa = sum - ac - bnc // newb = sum - bc - anc int newa = alg_sum(sm, ac, k); newa = alg_sum(newa, bnc, k); int newb = alg_sum(sm, bc, k); newb = alg_sum(newb, anc, k); return {newa, newb}; } // 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] ) { opt = operations; opr = operands; siz = la + lb; int n = la / 21; for (int i = 0; i < 16; ++i) { new_op(0, 0, OP_ZERO); } vector<int> answers(n); for (int i = 0; i < n; ++i) { answers[i] = la + lb; } for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { int val = alg_mult(16 * i, la + 16 * (i * n + j), 16); answers[j] = alg_sum(val, answers[j], 16); } } vector<int> permut(n); for (int i = 0; i < n; ++i) { permut[i] = 16 * n + i * 5; } for (int t = 0; t < n + 5; ++t) { vector<int> conds; for (int i = t % 2; i + 1 < n; i += 2) { conds.push_back(alg_gr(permut[i + 1], permut[i], 5)); } for (int i = t % 2; i + 1 < n; i += 2) { auto [pi, pj] = swap_if(permut[i], permut[i + 1], conds[i / 2], 5); auto [vi, vj] = swap_if(answers[i], answers[i + 1], conds[i / 2], 16); permut[i] = pj; permut[i + 1] = pi; answers[i] = vj; answers[i + 1] = vi; } } for (int i = 0; i < n; ++i) { for (int j = 0; j < 16; ++j) { outputs_circuit[i][j] = answers[i] + j; } } return siz; }
#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...