Submission #1175893

#TimeUsernameProblemLanguageResultExecution timeMemory
1175893Zero_OPAncient Machine (JOI21_ancient_machine)C++20
100 / 100
110 ms6856 KiB
#include "Anna.h" #include <bits/stdc++.h> using namespace std; namespace { #define sz(v) (int)v.size() #define pb push_back using bigint = vector<int>; //reversed order const int base = 2; bigint operator + (bigint a, bigint b){ int n = max(sz(a), sz(b)); a.resize(n); b.resize(n); bigint c(n); int carry = 0; for(int i = 0; i < n; ++i){ c[i] = a[i] + b[i] + carry; if(c[i] >= base){ carry = 1; c[i] -= base; } else carry = 0; } if(carry) c.pb(carry); while(!c.empty() && c.back() == 0) c.pop_back(); return c; } void show(const bigint& n){ if(n.empty()){ cout << 0 << '\n'; } else{ for(int i = sz(n)-1; i >= 0; --i) cout << n[i]; cout << '\n'; } } bool is_greater_or_equal(const bigint& a, const bigint& b){ cout << "comparison :\n"; show(a); show(b); cout << '\n'; if(sz(a) != sz(b)) return sz(a) > sz(b); for(int i = sz(a)-1; i >= 0; --i){ if(a[i] != b[i]) return a[i] > b[i]; } return true; //equal } bigint operator - (bigint a, bigint b){ //assume that a >= b int n = max(sz(a), sz(b)); a.resize(n); b.resize(n); int carry = 0; bigint c(n); for(int i = 0; i < n; ++i){ c[i] = a[i] - b[i] - carry; if(c[i] < 0){ c[i] += base; carry = 1; } else carry = 0; } while(!c.empty() && c.back() == 0) c.pop_back(); return c; } } void Anna(int N, vector<char> S){ int f = -1; for(int i = 0; i < N; ++i){ if(S[i] == 'X'){ f = i; break; } } if(f == -1){ Send(0); return; } int nf = f; while(nf + 1 < N && S[nf+1] == 'Z') ++nf; vector<bool> bit(N); bit[f] = true; for(int i = nf + 1; i < N; ++i){ if(S[i] == 'Z') { while(i+1 < N && S[i+1] == 'Z') ++i; bit[i] = true; } } vector<bigint> fib(501); fib[0] = {1}, fib[1] = {0, 1}, fib[2] = {1, 1}; for(int i = 3; i < sz(fib); ++i){ fib[i] = fib[i-1] + fib[i-2]; } const int T = 498; const int B = 348; // cout << "Anna Send : "; // for(int i = 0; i < N; ++i) cout << bit[i]; cout << '\n'; for(int l = 0; l < N; l += T){ int r = min(N, l + T); bigint sum; for(int i = l; i < r; ++i){ if(bit[i]){ sum = sum + fib[i - l]; } } assert(sz(sum) < B); sum.resize(B); // show(sum); for(int i = 0; i < B; ++i){ Send(sum[i]); } } if(nf == f){ for(int i = 0; i < 17; ++i) Send(1); } else{ for(int i = 0; i < 17; ++i) Send(nf >> i & 1); } }
#include "Bruno.h" #include <bits/stdc++.h> using namespace std; namespace { #define sz(v) (int)v.size() #define pb push_back #define dbg(x) "[" #x " = " << (x) << "]" using bigint = vector<short>; //reversed order const int base = 2; bigint operator + (bigint a, bigint b){ int n = max(sz(a), sz(b)); a.resize(n); b.resize(n); bigint c(n); int carry = 0; for(int i = 0; i < n; ++i){ c[i] = a[i] + b[i] + carry; if(c[i] >= base){ carry = 1; c[i] -= base; } else carry = 0; } if(carry) c.pb(carry); while(!c.empty() && c.back() == 0) c.pop_back(); return c; } void show(const bigint& n){ if(n.empty()){ cout << 0 << '\n'; } else{ for(int i = sz(n)-1; i >= 0; --i) cout << n[i]; cout << '\n'; } } bool is_greater_or_equal(const bigint& a, const bigint& b){ // cout << "comparison :\n"; // show(a); // show(b); // cout << '\n'; // cout << sz(a) << ' ' << sz(b) << '\n'; if(sz(a) != sz(b)) return sz(a) > sz(b); for(int i = sz(a)-1; i >= 0; --i){ // cout << dbg(i) << dbg(a[i]) << dbg(b[i]) << '\n'; if(a[i] != b[i]) { // cout << dbg(i) << dbg(a[i]) << dbg(b[i]) << '\n'; return a[i] > b[i]; } } return true; //equal } bigint operator - (bigint a, bigint b){ //assume that a >= b int n = max(sz(a), sz(b)); a.resize(n); b.resize(n); int carry = 0; bigint c(n); for(int i = 0; i < n; ++i){ c[i] = a[i] - b[i] - carry; if(c[i] < 0){ c[i] += base; carry = 1; } else carry = 0; } return c; } } void Bruno(int N, int L, vector<int> A){ if(L == 1){ for(int i = 0; i < N; ++i) Remove(i); return; } vector<bigint> fib(501); fib[0] = {1}, fib[1] = {0, 1}, fib[2] = {1, 1}; for(int i = 3; i < sz(fib); ++i){ fib[i] = fib[i-1] + fib[i-2]; } const int T = 498; const int B = 348; for(int i = 0; i < sz(fib); ++i) fib[i].resize(B); int nBlocks = L / B; vector<bool> bit(N); for(int b = 0; b < nBlocks; ++b){ int l = b * B, r = (b + 1) * B; bigint sum; for(int i = l; i < r; ++i){ sum.pb(A[i]); } // show(sum); for(int i = T; i >= 0; --i){ // show(sum); // show(fib[i]); // bool x = is_greater_or_equal(sum, fib[i]); // cout << dbg(x) << '\n'; if(is_greater_or_equal(sum, fib[i])){ // return; sum = sum - fib[i]; assert(sz(sum) == B); bit[i + (b * T)] = 1; } } } // cout << "Bruno Receive :"; // for(int i = 0; i < N; ++i) cout << bit[i]; cout << '\n'; int extra = 0; for(int i = 0; i < 17; ++i){ if(A[i + nBlocks * B]) extra |= (1 << i); } int f = -1; for(int i = 0; i < N; ++i){ if(bit[i]){ f = i; break; } } int s = -1; for(int i = N - 1; i >= 0; --i){ if(bit[i]){ s = i; break; } } vector<int> result; for(int i = 0; i < f; ++i) result.push_back(i); for(int i = N-1; i > s; --i) result.push_back(i); int old = -1; if(extra < N){ old = f; f = extra; for(int i = old + 1; i <= f; ++i) result.push_back(i); } int last = f; for(int i = f + 1; i <= s; ++i){ if(bit[i]){ for(int j = i-1; j > last; --j) result.push_back(j); result.push_back(i); last = i; } } if(old != -1) result.push_back(old); else result.push_back(f); for(int i = 0; i < N; ++i) Remove(result[i]); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...