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 "encoder.h"
#include "encoderlib.h"
#include "decoder.h"
#include "decoderlib.h"
#include<bits/stdc++.h>
using namespace std;
// #define int long long
#define vt vector
#define pb push_back
#define X first
#define Y second
using pii = pair<int,int>;
#define debug(x) do\
{auto _x=x; cerr<<#x<<" = "<<_x<<'\n';}while(0);
#define f0r(i,a,b) for(auto i=(a);i<(b);i++)
#define r0f(i,a,b) for(auto i=(a);i>=(b);i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#define cerr while(0) cerr
//BUG: forgot to squeeze memory limit
//Stars and bars
//320 elements, 255 splitting points
//C(575, 255)
//from [0, 256)
//Convert bits into big integer
//be careful of leading 0s in decoder
//Find R-th combination: C(n,k,R)
//then sweep thru, unchosen elements = d
//chosen elements -> d++
//bug: chosen elements don't count towards total
//account for leading 0s
//use binary search lemma
//encoding: message -> (str append) bits -> (roll) order number
//-> (swipe + myror) chosen -> (splay) sorted sequence
// 100 * 9 bits
namespace {
const long long base = 1e9;
using ll = vt<int>;
//just make sure not a multiple of 5
const int digits = 27;
ll itov(int k) {
vt<int> res (digits);
res[digits-1] = k;
return res;
}
vt<vt<ll>> cdp (600, vt<ll> (600, itov(-1)));
ostream& operator<<(ostream &lol, const ll &a) {
bool IS_BIGNUM = sz(a) == digits;
int lz = 0;
if(IS_BIGNUM) {
while(lz < sz(a) and a[lz] == 0) lz++; //BUG: almost segfaulted
}
//BUG: size of a instead of digits
f0r(i,lz,sz(a)) {
if(i == lz) lol << a[i] << ' ';
else lol << a[i] << ' ';
}
if(lz >= sz(a) and lz != 0) lol << 0;
return lol;
}
ll operator+(const ll &a, const ll &b) {
ll c (digits);
int carry = 0;
r0f(i,digits-1,0) {
long long sum = (a[i] + b[i] + carry);
c[i] = sum % base;
carry = sum / base;
}
// debug(a) debug(b) debug(c)
return c;
}
ll operator-(const ll &a, const ll &b) {
assert(a >= b);
ll c (digits);
int carry = 0;
r0f(i,digits-1,0) {
long long diff = (a[i] - b[i] - carry);
int nc = 0;
while(diff < 0) nc++, diff += base;
c[i] = diff;
//BUG: forgot to set c[i] = diff
carry = nc;
}
// debug(a)
// debug(b)
// debug(c);
return c;
}
ll operator/(const ll &a, int b) { //short division
ll res (digits);
int carry = 0;
f0r(i,0,digits) {
int ds = carry * base + a[i];
res[i] = ds / b;
carry = ds % b;
}
// debug(a) debug(res)
return res;
}
ll comb(int n, int k) {
if(k == 0) return itov(1);
if(n == 0) return itov(0);
if(cdp[n][k] != itov(-1)) return cdp[n][k];
return cdp[n][k] = comb(n-1,k-1) + comb(n-1,k);
}
//BUG: RE = Infinite recursion
//Also, don't use directly
void swipe(int n, int k, ll R, vt<int> &ans) {
if(n == 0 or k == 0) return;
// debug(n) debug(k) debug(R)
ll a = comb(n-1,k);
ll b = comb(n-1,k-1);
// debug(a) debug(b)
// assert(R <= (a+b)); currently buggy??
// if(R <= a) {
// swipe(n-1,k,R,ans);
// } else {
// swipe(n-1,k-1,R-a,ans);
// ans.pb(n-1); //0-indexing business
// }
assert(R <= (a+b));
// debug(R)
if(R <= b) {
// debug("I chose") debug(n) debug(k)
ans.pb(n-1);
swipe(n-1,k-1,R,ans);
} else {
// debug("I didn't choose") debug(n) debug(k)
swipe(n-1,k,R-b,ans);
}
}
//This function should work
vt<int> myror(int n, int k, ll R) {
vt<int> ans;
swipe(n, k, R, ans);
f0r(i,0,sz(ans)) {
ans[i] = n-1-ans[i];
}
// debug(n) debug(k) debug(R)
// debug(ans);
return ans;
}
vt<int> splay(vt<int> co, int N) {
debug("splay")
const int sbars = 5*N + 255;
vt<bool> chose (sbars);
f0r(i,0,sz(co)) {
assert(co[i] < sbars);
chose[co[i]] = 1;
}
vt<int> res;
int d = 0;
f0r(i,0,sbars) {
if(chose[i]) {
d++;
} else {
res.pb(d);
}
}
return res;
}
//decoding: sorted sequence -> (while loop and cur diff) chosen -> (guess binary search, div2) order number
//->(division roll method) bits -> (pad zeroes and stoi spam) message
ll inv(vt<int> a, int N, int K) {
ll res = itov(0);
assert(sz(a) == K);
f0r(i,0,sz(a)) {
int prev = i == 0 ? -1 : a[i-1];
f0r(s,prev+1, a[i]) {
res = res + comb(N-1-s, K-i-1);
}
}
res = res + itov(1);
return res;
}
void mydec(signed msz, signed N, signed xs[]) {
sort(xs,xs+N);
int ck = 255;
int cn = N + 255;
debug(cn) debug(ck);
vt<int> chose; //0,1 array
int c_walk = 0;
f0r(i,0,N) {
while(c_walk != xs[i]) c_walk++, chose.pb(1);
chose.pb(0);
}
//BUG: mixed up order of operations LMAO
//need to account for leading zeroes before constructing need, otherwise useless
//edge case: ending 1s
while(c_walk != 255) c_walk++, chose.pb(1);
vt<int> need; //chosen elements
f0r(i,0,sz(chose)) {
if(chose[i]) {
need.pb(i);
}
}
// ll lo = itov(1), hi = itov(1), ord = itov(-1);
// f0r(_,0,8*65) { //repeated doublings???
// hi = hi + hi;
// }
//binary search on order number
// auto check = [&](ll wow) -> bool {
// //BUG: check if wow is even in the order number range
// if(wow > comb(cn, ck)) {
// return false;
// }
// vt<int> cur = myror(cn, ck, wow);
// if(cur <= need) {
// return true;
// } else {
// return false;
// }
// };
// debug(need);
// while(lo <= hi) {
// ll mid = (lo+hi)/2;
// // debug(lo) debug(hi) debug(mid)
// // debug(mid+itov(1));
// // debug(mid-itov(1));
// if(check(mid)) {
// lo = mid+itov(1);
// ord = mid;
// } else {
// hi = mid-itov(1);
// }
// }
// if(myror(cn,ck,ord+itov(6)) == need) {
// debug("WTF");
// }
// assert(myror(cn,ck,ord) == need);
// debug(ord);
ll ord = inv(need, cn, ck);
//BUG: order number + 1
ll pay = ord - itov(1);
string bits;
while(pay != itov(0)) { //BUG: Inf loop here
if(pay[digits-1] % 2 == 1) {
bits += '1';
} else {
bits += '0';
}
//BUG: lmao forgot to set pay = pay/2
pay = pay / 2;
}
while(sz(bits) != 8 * msz) { //bit string
bits += '0';
}
reverse(all(bits));
assert(sz(bits) % 8 == 0);
vt<int> ans;
debug("DECODING BITS")
debug(bits);
for(int ptr = 0; ptr < sz(bits); ptr += 8) {
string block = bits.substr(ptr, 8);
int ayy = stoi(block, nullptr, 2);
ans.pb(ayy);
}
debug("I THINK...")
for(int x : ans) {
cerr << x << ' ';
output(x);
}
cerr << '\n';
}
void myenc(signed N, signed M[]) {
// cdp = vt<vt<ll>> (600, vt<ll> (600, -1));
// assert(N == 8);
string bits;
//load input bit and trick
//BUG: highest significant bit first, lmao
f0r(i,0,N) {
r0f(b,7,0) {
if(M[i] & (1 << b)) {
bits += '1';
} else {
bits += '0';
}
}
}
debug("ENCODING BITS")
debug(bits);
ll ord = itov(0);
ll roll = itov(1);
debug("ayo")
r0f(i,sz(bits)-1,0) {
if(bits[i] == '1') {
ord = ord + roll;
}
roll = roll + roll;
}
ord = ord + itov(1); //BUG: 0 case is bad
debug(ord);
//bug: forgot to + 255
vt<int> co = myror(5*N + 255, 255, ord);
// debug(ord);
// swipe(575,255,ord,co);
// debug(co);
debug(co);
vt<int> ans = splay(co, N);
assert(sz(ans) == 5*N);
debug("here's my answer");
for(int x : ans) {
cerr << x << ' ';
}
cerr << '\n';
for(int x : ans) {
send(x);
}
}
};
void encode(signed N, signed M[]) {
myenc(N, M);
}
// void decode(signed msz, signed N, signed xs[]) {
// mydec(msz, N, xs);
// }
#include "encoder.h"
#include "encoderlib.h"
#include "decoder.h"
#include "decoderlib.h"
#include<bits/stdc++.h>
using namespace std;
// #define int long long
#define vt vector
#define pb push_back
#define X first
#define Y second
using pii = pair<int,int>;
#define debug(x) do\
{auto _x=x; cerr<<#x<<" = "<<_x<<'\n';}while(0);
#define f0r(i,a,b) for(auto i=(a);i<(b);i++)
#define r0f(i,a,b) for(auto i=(a);i>=(b);i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#define cerr while(0) cerr
//BUG: forgot to squeeze memory limit
//Stars and bars
//320 elements, 255 splitting points
//C(575, 255)
//from [0, 256)
//Convert bits into big integer
//be careful of leading 0s in decoder
//Find R-th combination: C(n,k,R)
//then sweep thru, unchosen elements = d
//chosen elements -> d++
//bug: chosen elements don't count towards total
//account for leading 0s
//use binary search lemma
//encoding: message -> (str append) bits -> (roll) order number
//-> (swipe + myror) chosen -> (splay) sorted sequence
// 100 * 9 bits
namespace {
const long long base = 1e9;
using ll = vt<int>;
//just make sure not a multiple of 5
const int digits = 27;
ll itov(int k) {
vt<int> res (digits);
res[digits-1] = k;
return res;
}
vt<vt<ll>> cdp (600, vt<ll> (600, itov(-1)));
ostream& operator<<(ostream &lol, const ll &a) {
bool IS_BIGNUM = sz(a) == digits;
int lz = 0;
if(IS_BIGNUM) {
while(lz < sz(a) and a[lz] == 0) lz++; //BUG: almost segfaulted
}
//BUG: size of a instead of digits
f0r(i,lz,sz(a)) {
if(i == lz) lol << a[i] << ' ';
else lol << a[i] << ' ';
}
if(lz >= sz(a) and lz != 0) lol << 0;
return lol;
}
ll operator+(const ll &a, const ll &b) {
ll c (digits);
int carry = 0;
r0f(i,digits-1,0) {
long long sum = (a[i] + b[i] + carry);
c[i] = sum % base;
carry = sum / base;
}
// debug(a) debug(b) debug(c)
return c;
}
ll operator-(const ll &a, const ll &b) {
assert(a >= b);
ll c (digits);
int carry = 0;
r0f(i,digits-1,0) {
long long diff = (a[i] - b[i] - carry);
int nc = 0;
while(diff < 0) nc++, diff += base;
c[i] = diff;
//BUG: forgot to set c[i] = diff
carry = nc;
}
// debug(a)
// debug(b)
// debug(c);
return c;
}
ll operator/(const ll &a, int b) { //short division
ll res (digits);
int carry = 0;
f0r(i,0,digits) {
int ds = carry * base + a[i];
res[i] = ds / b;
carry = ds % b;
}
// debug(a) debug(res)
return res;
}
ll comb(int n, int k) {
if(k == 0) return itov(1);
if(n == 0) return itov(0);
if(cdp[n][k] != itov(-1)) return cdp[n][k];
return cdp[n][k] = comb(n-1,k-1) + comb(n-1,k);
}
//BUG: RE = Infinite recursion
//Also, don't use directly
void swipe(int n, int k, ll R, vt<int> &ans) {
if(n == 0 or k == 0) return;
// debug(n) debug(k) debug(R)
ll a = comb(n-1,k);
ll b = comb(n-1,k-1);
// debug(a) debug(b)
// assert(R <= (a+b)); currently buggy??
// if(R <= a) {
// swipe(n-1,k,R,ans);
// } else {
// swipe(n-1,k-1,R-a,ans);
// ans.pb(n-1); //0-indexing business
// }
assert(R <= (a+b));
// debug(R)
if(R <= b) {
// debug("I chose") debug(n) debug(k)
ans.pb(n-1);
swipe(n-1,k-1,R,ans);
} else {
// debug("I didn't choose") debug(n) debug(k)
swipe(n-1,k,R-b,ans);
}
}
//This function should work
vt<int> myror(int n, int k, ll R) {
vt<int> ans;
swipe(n, k, R, ans);
f0r(i,0,sz(ans)) {
ans[i] = n-1-ans[i];
}
// debug(n) debug(k) debug(R)
// debug(ans);
return ans;
}
vt<int> splay(vt<int> co, int N) {
debug("splay")
const int sbars = 5*N + 255;
vt<bool> chose (sbars);
f0r(i,0,sz(co)) {
assert(co[i] < sbars);
chose[co[i]] = 1;
}
vt<int> res;
int d = 0;
f0r(i,0,sbars) {
if(chose[i]) {
d++;
} else {
res.pb(d);
}
}
return res;
}
//decoding: sorted sequence -> (while loop and cur diff) chosen -> (guess binary search, div2) order number
//->(division roll method) bits -> (pad zeroes and stoi spam) message
ll inv(vt<int> a, int N, int K) {
ll res = itov(0);
assert(sz(a) == K);
f0r(i,0,sz(a)) {
int prev = i == 0 ? -1 : a[i-1];
f0r(s,prev+1, a[i]) {
res = res + comb(N-1-s, K-i-1);
}
}
res = res + itov(1);
return res;
}
void mydec(signed msz, signed N, signed xs[]) {
sort(xs,xs+N);
int ck = 255;
int cn = N + 255;
debug(cn) debug(ck);
vt<int> chose; //0,1 array
int c_walk = 0;
f0r(i,0,N) {
while(c_walk != xs[i]) c_walk++, chose.pb(1);
chose.pb(0);
}
//BUG: mixed up order of operations LMAO
//need to account for leading zeroes before constructing need, otherwise useless
//edge case: ending 1s
while(c_walk != 255) c_walk++, chose.pb(1);
vt<int> need; //chosen elements
f0r(i,0,sz(chose)) {
if(chose[i]) {
need.pb(i);
}
}
// ll lo = itov(1), hi = itov(1), ord = itov(-1);
// f0r(_,0,8*65) { //repeated doublings???
// hi = hi + hi;
// }
//binary search on order number
// auto check = [&](ll wow) -> bool {
// //BUG: check if wow is even in the order number range
// if(wow > comb(cn, ck)) {
// return false;
// }
// vt<int> cur = myror(cn, ck, wow);
// if(cur <= need) {
// return true;
// } else {
// return false;
// }
// };
// debug(need);
// while(lo <= hi) {
// ll mid = (lo+hi)/2;
// // debug(lo) debug(hi) debug(mid)
// // debug(mid+itov(1));
// // debug(mid-itov(1));
// if(check(mid)) {
// lo = mid+itov(1);
// ord = mid;
// } else {
// hi = mid-itov(1);
// }
// }
// if(myror(cn,ck,ord+itov(6)) == need) {
// debug("WTF");
// }
// assert(myror(cn,ck,ord) == need);
// debug(ord);
ll ord = inv(need, cn, ck);
//BUG: order number + 1
ll pay = ord - itov(1);
string bits;
while(pay != itov(0)) { //BUG: Inf loop here
if(pay[digits-1] % 2 == 1) {
bits += '1';
} else {
bits += '0';
}
//BUG: lmao forgot to set pay = pay/2
pay = pay / 2;
}
while(sz(bits) != 8 * msz) { //bit string
bits += '0';
}
reverse(all(bits));
assert(sz(bits) % 8 == 0);
vt<int> ans;
debug("DECODING BITS")
debug(bits);
for(int ptr = 0; ptr < sz(bits); ptr += 8) {
string block = bits.substr(ptr, 8);
int ayy = stoi(block, nullptr, 2);
ans.pb(ayy);
}
debug("I THINK...")
for(int x : ans) {
cerr << x << ' ';
output(x);
}
cerr << '\n';
}
void myenc(signed N, signed M[]) {
// cdp = vt<vt<ll>> (600, vt<ll> (600, -1));
// assert(N == 8);
string bits;
//load input bit and trick
//BUG: highest significant bit first, lmao
f0r(i,0,N) {
r0f(b,7,0) {
if(M[i] & (1 << b)) {
bits += '1';
} else {
bits += '0';
}
}
}
debug("ENCODING BITS")
debug(bits);
ll ord = itov(0);
ll roll = itov(1);
debug("ayo")
r0f(i,sz(bits)-1,0) {
if(bits[i] == '1') {
ord = ord + roll;
}
roll = roll + roll;
}
ord = ord + itov(1); //BUG: 0 case is bad
debug(ord);
//bug: forgot to + 255
vt<int> co = myror(5*N + 255, 255, ord);
// debug(ord);
// swipe(575,255,ord,co);
// debug(co);
debug(co);
vt<int> ans = splay(co, N);
assert(sz(ans) == 5*N);
debug("here's my answer");
for(int x : ans) {
cerr << x << ' ';
}
cerr << '\n';
for(int x : ans) {
send(x);
}
}
};
// void encode(signed N, signed M[]) {
// myenc(N, M);
// }
void decode(signed msz, signed N, signed xs[]) {
mydec(msz, N, xs);
}
Compilation message (stderr)
encoder.cpp:180:6: warning: 'void {anonymous}::mydec(int, int, int*)' defined but not used [-Wunused-function]
180 | void mydec(signed msz, signed N, signed xs[]) {
| ^~~~~
decoder.cpp:271:6: warning: 'void {anonymous}::myenc(int, int*)' defined but not used [-Wunused-function]
271 | void myenc(signed N, signed M[]) {
| ^~~~~
# | 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... |