QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#115328#2351. Lost in Transferckiseki#0 2ms3444kbC++204.7kb2023-06-25 19:12:192023-06-25 19:12:20

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-06-25 19:12:20]
  • 评测
  • 测评结果:0
  • 用时:2ms
  • 内存:3444kb
  • [2023-06-25 19:12:19]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

#ifdef CKISEKI
#define safe cerr << __PRETTY_FUNCTION__ << " line " << __LINE__ << " safe\n"
#define debug(a...) debug_(#a, a)
#define orange(a...) orange_(#a, a)
template <typename ...T>
void debug_(const char *s, T ...a) {
    cerr << "\e[1;32m(" << s << ") = (";
    int cnt = sizeof...(T);
    (..., (cerr << a << (--cnt ? ", " : ")\e[0m\n")));
}
template <typename I>
void orange_(const char *s, I L, I R) {
    cerr << "\e[1;32m[ " << s << " ] = [ ";
    for (int f = 0; L != R; ++L)
        cerr << (f++ ? ", " : "") << *L;
    cerr << " ]\e[0m\n";
}
#else
#define safe ((void)0)
#define debug(...) safe
#define orange(...) safe
#endif
#define all(v) begin(v),end(v)

using namespace std;
using VI = vector<int>;

const int C = 10;
const int S = 512;
const int M = 317;

mt19937 rng(1238009);

using lld = int64_t;

lld fac[20] = {};
lld getNum(vector<int> p, int n) {
    if (n == 1)
        return 0;

    for (int i = 0; i < n; i++)
        if (p[i] == n-1) {
            swap(p[i], p[n-1]);
            return i * fac[n-1] + getNum(p, n - 1);
        }
    __builtin_unreachable();
}

void restore(lld num, vector<int> &p, int n) {
    if (n == 1) {
        assert (num == 0);
        p[0] = 0;
        return;
    }
    debug(n, fac[n-1]);
    restore(num % fac[n-1], p, n-1);
    int i = num / fac[n-1];
    p[n-1] = n-1;
    swap(p[i], p[n-1]);
}

pair<VI, VI> genPerm(int x, int k1, int k2) {
    VI p1(C);
    VI p2(C);
    // iota(all(p1), 0);
    // iota(all(p2), 0);
    // shuffle(all(p1), rng);
    // shuffle(all(p2), rng);

    restore(x + S * M * k1, p1, C);
    restore(x + S * M * k2, p2, C);
    debug(getNum(p1, C), x + S * M * k1);
    debug(getNum(p2, C), x + S * M * k2);
    return { p1, p2 };
}

vector<int> recover(vector<int>);

vector<int> transmit(vector<int> a) {
    int n = a.size();
    int xo = 0;
    for (int x: a) xo ^= x;

    sort(a.begin(), a.end());
    for (int k1 = 0; k1 < 20; k1++) {
        for (int k2 = 0; k2 < 20; k2++) {
            auto [p1, p2] = genPerm(xo, k1, k2);
            orange(all(p1));
            orange(all(p2));

            auto b = a;
            for (int i = 0; i < C; i++)
                b[i] = a[p1[i]];
            for (int i = 0; i < C; i++)
                b[n-C+i] = a[n-C+p2[i]];

            bool ok = (recover(b) == a);
            for (int i = 0; i < n && ok; i++) {
                auto tb = b;
                tb.erase(tb.begin() + i);
                if (recover(b) != a) {
                    ok = false;
                    break;
                }
            }
            if (ok)
                return b;
        }
    }

    __builtin_unreachable();
}

vector<int> recover(vector<int> b) {
    int m = b.size();
    vector<pair<int,int>> pr1, pr2;
    for (int i = 0; i < C; i++) {
        pr1.emplace_back(b[i], i);
    }
    for (int i = 0; i < C; i++) {
        pr2.emplace_back(b[m-C+i], i);
    }
    assert (pr1.size() == C && pr2.size() == C);
    vector<int> p1(C), p2(C);
    sort(pr1.begin(), pr1.end());
    sort(pr2.begin(), pr2.end());

    for (int i = 0; i < C; i++)
        p1[pr1[i].second] = i;
    for (int i = 0; i < C; i++)
        p2[pr2[i].second] = i;

    orange(all(p1));
    orange(all(p2));

    lld x1 = getNum(p1, C);
    lld x2 = getNum(p1, C);
    lld x = 0;
    if ((x1 / 512) % M == 0) {
        x = x1 % 512;
    } else if ((x2 / 512) % M == 0) {
        x = x2 % 512;
    }
    for (int z: b)
        x ^= z;
    if (x != 0) {
        b.push_back(x);
    }
    sort(b.begin(), b.end());

    return b;
}

void test() {
    VI a(500);
    iota(a.begin(), a.end(), 1);
    shuffle(a.begin(), a.end(), rng);
    a.resize(20);
    assert (set(a.begin(), a.end()).size() == a.size());
    assert (a.size() >= 20);
    auto b = transmit(a);
    recover(b);
}

int main() {
    fac[0] = 1;
    for (int i = 1; i <= 10; i++)
        fac[i] = fac[i - 1] * i;
    cin.tie(nullptr)->sync_with_stdio(false);

    // test();
    // return 0;

    string type;
    cin >> type;
    if (type == "transmit") {
        int T;
        cin >> T;
        while (T--) {
            int n;
            cin >> n;
            vector<int> a(n);
            for (int i = 0; i < n; i++)
                cin >> a[i];
            auto b = transmit(a);
            for (int i = 0; i < n; i++)
                cout << b[i] << (i+1==n ? '\n' : ' ');
        }
    } else if (type == "recover") {
        int T;
        cin >> T;
        while (T--) {
            int m;
            cin >> m;
            vector<int> b(m);
            for (int i = 0; i < m; i++)
                cin >> b[i];
            auto a = recover(b);
            int n = a.size();
            for (int i = 0; i < n; i++)
                cout << a[i] << (i+1==n ? '\n' : ' ');
        }
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 2ms
memory: 3444kb

input:

transmit
2
20 97 388 459 467 32 99 98 296 403 325 330 271 87 333 378 267 405 58 426 374
20 125 481 451 150 495 136 444 192 118 26 68 281 120 61 494 339 86 292 100 32

output:

325 99 32 58 87 97 98 267 271 296 467 403 330 333 374 378 388 405 426 459
136 86 32 68 61 26 100 118 120 125 495 339 192 292 281 150 444 451 481 494

input:

recover
2
19 325 99 32 58 87 97 98 267 271 296 467 403 330 333 374 378 388 405 426 
19 136 86 32 68 26 100 118 120 125 495 339 192 292 281 150 444 451 481 494 

output:

32 58 87 97 98 99 267 271 296 325 330 333 374 378 388 403 405 426 459 467
16 26 32 68 86 100 118 120 125 136 150 192 281 292 339 444 451 481 494 495

result:

wrong answer incorrect answer. (test case 2)