제출 #1195571

#제출 시각아이디문제언어결과실행 시간메모리
1195571tutis메시지 (IOI24_message)C++20
0 / 100
3426 ms1644 KiB
#include "message.h" #include <algorithm> #include <chrono> #include <iostream> #include <random> #include <bitset> #include <vector> #include <deque> #include <assert.h> #include <math.h> using namespace std; int counter = 0; bitset<31> masks[200]; int choose[32][32]; const int64_t seed1 = 5; int tests = 10000; bitset<31> globC; bool initialized = false; mt19937_64 rngSending(0); bitset<31> send(bitset<31> A, bitset<31> C) { if (counter >= 199) { assert(false); } A = A ^ masks[counter]; vector<bool> Avector(31); for (int i = 0; i < 31; i++) { Avector[i] = A[i]; if (C[i]) { Avector[i] = rngSending() % 2; } } vector<bool> recVector = send_packet(Avector); bitset<31> received; for (int j = 0; j < 31; j++) { received[j] = recVector[j]; } received = received ^ masks[counter]; counter++; return received; } const int Q = 66; int pos(bitset<31> C, int n, int k) { if (k == 0) { return 1; } if (C[n - 1]) { return choose[n - 1][k] + pos(C, n - 1, k - 1); } else { return pos(C, n - 1, k); } } bitset<31> kth(int n, int k, int pos) { if (pos > choose[n][k]) { return 0; } if (n == k) { bitset<31> ret; for (int i = 0; i < n; i++) { ret[i] = true; } return ret; } if (k == 0) { return bitset<31>(0); } if (pos <= choose[n - 1][k]) { return kth(n - 1, k, pos); } bitset<31> c = kth(n - 1, k - 1, pos - choose[n - 1][k]); c[n - 1] = true; return c; } deque<bool> prepareBits(vector<bool> M, bitset<31> C) { deque<bool> X; mt19937_64 rng(C.to_ullong()); int offset = 1024 - M.size(); for (int i = 0; i < offset; i++) { X.push_back(1); } X.push_back(0); for (int v : M) { X.push_back(v); } for (int i = 0; i < Q * 16 - 1025 - 23; i++) { X.push_back(rng() % 2 == 1); } assert(X.size() == Q * 16 - 23); return X; } void init() { counter = 0; if (!initialized) { for (int n = 0; n < 32; n++) { for (int k = 0; k <= n; k++) { if (k == 0 || n == 0) { choose[n][k] = 1; } else { choose[n][k] = choose[n - 1][k] + choose[n - 1][k - 1]; } } } mt19937_64 rng(seed1); for (int i = 0; i < 200; i++) { for (int j = 0; j < 31; j++) { masks[i] = rng(); } } } initialized = true; } void send_message(vector<bool> M, vector<bool> Cvect) { init(); bitset<31> C; for (int i = 0; i < 31; i++) { C[i] = Cvect[i]; } globC = C; bitset<29> CC = pos(C, 31, 15); deque<bool> X = prepareBits(M, C); int pos = (CC.to_ullong() - 1) / 6678671; // 0...44 assert(pos < 45); bitset<23> posBits = (CC.to_ullong() - 1) % 6678671; vector<bitset<31>> V(Q); int c = 0; for (int j = 0; j < 31; j++) { if (C[j]) { continue; } for (int i = 0; i < Q; i++) { if (c / 23 == pos) { V[i][j] = posBits[c % 23]; } else { V[i][j] = X.front(); X.pop_front(); } c++; } } for (bitset<31> v : V) { send(v, C); } } std::vector<bool> receive_message(vector<vector<bool>> Rvect) { init(); vector<bitset<31>> R(Rvect.size()); for (int i = 0; i < int(Rvect.size()); i++) { bitset<31> b; for (int j = 0; j < 31; j++) { b[j] = Rvect[i][j]; } R[i] = b; } for (int i = 0; i < int(R.size()); i++) { R[i] = R[i] ^ masks[i]; } if (R.size() != Q) { assert(false); } for (int pos = 0; pos < 45; pos++) { vector<bitset<29>> posCC; for (int c1 = 0; c1 <= 31; c1++) { for (int c2 = c1 + 1; c2 <= 32; c2++) { for (int s = 0; s < 66; s++) { vector<bool> bits; for (int i = s; i < 66; i++) { bits.push_back(R[i][c1]); } if (c2 != 32) { for (int i = 0; i < 66; i++) { bits.push_back(R[i][c2]); } } if (bits.size() < 23) { continue; } bitset<23> posBits; for (int i = 0; i < 23; i++) { posBits[i] = bits[i]; } posCC.push_back(posBits.to_ullong() + 6678671 * pos + 1); } } } for (bitset<29> cc : posCC) { bitset<31> C = kth(31, 15, cc.to_ullong()); if (C.count() != 15) { continue; } bitset<23> posBits = (cc.to_ullong() - 1) % 6678671; deque<bool> X; int c = 0; bool ok = true; for (int j = 0; j < 31; j++) { if (C[j]) { continue; } for (int i = 0; i < Q; i++) { if (c / 23 == pos) { ok &= R[i][j] == posBits[c % 23]; } else { X.push_back(R[i][j]); } c++; } } if (!ok) { continue; } mt19937_64 rng(C.to_ullong()); for (int i = 1025; i < int(X.size()); i++) { bool v = rng() % 2 == 1; bool w = X[i]; if (v != w) { ok = false; break; } } if (!ok) { continue; } while (X.size() > 1025) { X.pop_back(); } int offset = 0; while (offset < int(X.size()) && X[offset]) { offset++; } vector<bool> answer; for (int i = offset + 1; i < int(X.size()); i++) { answer.push_back(X[i]); } while (answer.size() < 1025) { answer.push_back(0); } while ((1024 - int(answer.size())) != offset && answer.size() > 0) { answer.pop_back(); } return answer; } } assert(false); return {}; } // vector<vector<bool>> sent; // int main() // { // mt19937_64 rng(6); // int maxQ = 0; // double avg = 0; // for (int i = 0; i < tests; i++) // { // vector<bool> msg(1024); // for (int i = 0; i < int(msg.size()); i++) // { // msg[i] = rng() % 2; // } // vector<bool> Cvect{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // shuffle(Cvect.begin(), Cvect.end(), rng); // send_message(msg, // Cvect); // vector<bool> received = receive_message(sent); // maxQ = max(maxQ, int(sent.size())); // avg += sent.size(); // if (msg != received) // { // cout << "maxQ: " << maxQ << " i: " << i << endl; // cout << "mismatch!" << endl; // for (int i : msg) // { // cout << i; // } // cout << endl; // for (int i : received) // { // cout << i; // } // cout << endl; // exit(0); // } // else // { // } // sent = {}; // } // cout << maxQ << " " << avg / tests << endl; // } // vector<bool> send_packet(std::vector<bool> A) // { // sent.push_back(A); // return A; // }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...