제출 #1323789

#제출 시각아이디문제언어결과실행 시간메모리
1323789nikaa123앵무새 (IOI11_parrots)C++20
0 / 100
25 ms12940 KiB
#include <bits/stdc++.h>
#include "encoder.h"
#include "encoderlib.h"
using namespace std;

int base = 1e9;

struct bigint {
    vector<int> d;
    bigint() {}
    bigint(long long res) {
        if (res == 0) d.emplace_back(0);
        while (res > 0) {
            d.emplace_back(res % 1000000000);
            res /= 1000000000;
        }
    }

    void add(const bigint& res) {
        int carry = 0;
        for (int i = 0; i < max(res.d.size(), d.size()) || carry; i++) {
            if (i == d.size()) d.emplace_back(0);
            long long cur = (long long)(res.d.size() > i ? res.d[i] : 0) + carry + d[i];
            d[i] = cur % 1000000000;
            carry = cur / 1000000000;
        }
    }

    void remove(const bigint& res) {
        int borrow = 0;
        for (int i = 0; i < res.d.size() || borrow; i++) {
            long long cur = (long long)d[i] - (res.d.size() > i ? res.d[i] : 0) - borrow;
            if (cur < 0) { borrow = 1; cur += 1000000000; }
            else borrow = 0;
            d[i] = (int)cur;
        }
        while (d.size() > 1 && d.back() == 0) d.pop_back();
    }

    void multily(int res) {
        if (res == 0) { d = {0}; return; }
        long long carry = 0;
        for (int i = 0; i < d.size() || carry; i++) {
            if (i == d.size()) d.emplace_back(0);
            long long cur = (long long)d[i] * res + carry;
            d[i] = cur % 1000000000;
            carry = cur / 1000000000;
        }
        while (d.size() > 1 && d.back() == 0) d.pop_back();
    }

    int divide(int res) {
        long long rem = 0;
        for (int i = (int)d.size() - 1; i >= 0; i--) {
            long long cur = d[i] + rem * 1000000000;
            d[i] = (int)(cur / res);
            rem = cur % res;
        }
        while (d.size() > 1 && d.back() == 0) d.pop_back();
        return (int)rem;
    }

    bool operator<(const bigint& res) const {
        if (d.size() != res.d.size()) return d.size() < res.d.size();
        for (int i = (int)d.size() - 1; i >= 0; i--)
            if (d[i] != res.d[i]) return d[i] < res.d[i];
        return false;
    }
};

bigint c[700][300]; 
bool done_pre = false;

void precomp(int n) {
    if (done_pre) return;
    c[0][0] = bigint(1);
    for (int i = 1; i <= 650; i++) {
        c[i][0] = bigint(1);
        for (int j = 1; j <= 260 && j <= i; j++) {
            c[i][j] = c[i-1][j];
            c[i][j].add(c[i-1][j-1]);
        }
    }
    done_pre = true;
}

void encode(int N, int M[]) {
    precomp(N);
    
    bigint res_limit(1);
    for (int i = 0; i < N; i++) res_limit.multily(256);
    
    int L = 0;
    while (c[L + 256][256] < res_limit) L++;

    bigint val(0);
    for (int i = N - 1; i >= 0; i--) {
        val.multily(256);
        val.add(bigint(M[i]));
    }

    int cur = L;
    for (int x = 0; x <= 255; x++) {
      int rem = 255-x;
        for (int k = 0; k <= cur; k++) {
            int nn = (cur - k) + rem-x-1;
            int kk = rem-x;
            if (val < c[nn][kk]) {
                for (int i = 0; i < k; i++) send(x);
                cur -= k;
                break;
            } else {
                val.remove(c[nn][kk]);
            }
        }
    }
}
#include <bits/stdc++.h>
#include "decoder.h"
#include "decoderlib.h"
using namespace std;

int base = 1e9;

struct bigint {
    vector<int> d;
    bigint() {}
    bigint(long long res) { 
        if (res == 0) d.emplace_back(0);
        while (res > 0) {
            d.emplace_back(res % 1000000000);
            res /= 1000000000;
        }
    }

    void add(const bigint& res) {
        int carry = 0;
        for (int i = 0; i < max(res.d.size(), d.size()) || carry; i++) {
            if (i == d.size()) d.emplace_back(0);
            long long cur = (long long)(res.d.size() > i ? res.d[i] : 0) + carry + d[i];
            d[i] = cur % 1000000000;
            carry = cur / 1000000000;
        }
    }

    void remove(const bigint& res) {
        int borrow = 0;
        for (int i = 0; i < res.d.size() || borrow; i++) {
            long long cur = (long long)d[i] - (res.d.size() > i ? res.d[i] : 0) - borrow;
            if (cur < 0) { borrow = 1; cur += 1000000000; }
            else borrow = 0;
            d[i] = (int)cur;
        }
        while (d.size() > 1 && d.back() == 0) d.pop_back();
    }

    void multily(int res) {
        if (res == 0) { d = {0}; return; }
        long long carry = 0;
        for (int i = 0; i < d.size() || carry; i++) {
            if (i == d.size()) d.emplace_back(0);
            long long cur = (long long)d[i] * res + carry;
            d[i] = cur % 1000000000;
            carry = cur / 1000000000;
        }
        while (d.size() > 1 && d.back() == 0) d.pop_back();
    }

    int divide(int res) {
        long long rem = 0;
        for (int i = (int)d.size() - 1; i >= 0; i--) {
            long long cur = d[i] + rem * 1000000000;
            d[i] = (int)(cur / res);
            rem = cur % res;
        }
        while (d.size() > 1 && d.back() == 0) d.pop_back();
        return (int)rem;
    }

    bool operator<(const bigint& res) const {
        if (d.size() != res.d.size()) return d.size() < res.d.size();
        for (int i = (int)d.size() - 1; i >= 0; i--)
            if (d[i] != res.d[i]) return d[i] < res.d[i];
        return false;
    }
};

bigint c[700][300]; 
bool done_pre = false;

void precomp(int n) {
    if (done_pre) return;
    c[0][0] = bigint(1);
    for (int i = 1; i <= 650; i++) {
        c[i][0] = bigint(1);
        for (int j = 1; j <= 260 && j <= i; j++) {
            c[i][j] = c[i-1][j];
            c[i][j].add(c[i-1][j-1]);
        }
    }
    done_pre = true;
}

void decode(int N, int L, int X[]) {
    precomp(N);
    
    int cnt[256] = {0};
    for (int i = 0; i < L; i++) cnt[X[i]]++;
    
    bigint v(0);
    int cur = L;
    for (int x = 0; x <= 255; x++) {
        int k = cnt[x];
        int rem_types = 255 - x;
        for (int i = 0; i < k; i++) {
            int nn = (cur - i) + rem_types - 1;
            int kk = rem_types - 1;
            v.add(c[nn][kk]);
        }
        cur -= k;
    }

    for (int i = 0; i < N; i++) {
        output(v.divide(256));
    }
}
#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...