Submission #1359562

#TimeUsernameProblemLanguageResultExecution timeMemory
1359562domiDark Ride (EGOI25_darkride)C++20
100 / 100
1 ms468 KiB
#include <bits/stdc++.h>

#define int long long
#define fi first
#define se second

#define sz(a) (int)((a).size())
#define all(a) (a).begin(), (a).end()

#define lsb(x) (x & (-x))
#define vi vector<int>
#define YES { cout << "YES" << endl; return; }
#define NO { cout << "NO" << endl; return; }

using ll = long long;
using pii = std::pair<int, int>;

const int NMAX = 3e4;
const int BITS = 15;

using namespace std;

struct Jury {
    int p[NMAX];
    int number_queries = 0;
    int N;

    void read() {
        cin >> N;

#ifndef EVAL

        for (int i = 0; i < N; i++) {
            cin >> p[i];
        }

        vector<int> fr(N, 0);
        for (int i = 0; i < N; i++) {
            if (p[i] < 0 || p[i] >= N)
                throw runtime_error("invalid value in permutation");
            fr[p[i]]++;
        }
        for (int i = 0; i < N; i++) {
            if (fr[i] != 1)
                throw runtime_error("not a permutation");
        }
#endif
    }

    int query(const string& s) {
        number_queries++;

        if ((int)s.size() != N)
            throw runtime_error("invalid query length");

#ifndef EVAL
        vector<int> lit(N, 0);

        for (int i = 0; i < N; i++) {
            if (s[i] == '1') {
                lit[p[i]] = 1;
            }
        }

        int screams = 0;
        for (int i = 1; i < N; i++) {
            if (lit[i] != lit[i - 1])
                screams++;
        }

        return screams;
#endif

#ifdef EVAL
        cout << "? " << s << endl;
        cout.flush();

        int res;
        cin >> res;
        return res;
#endif
    }

    void submit(int A, int B) {
#ifndef EVAL
        if (A < 0 || A >= N || B < 0 || B >= N || A == B)
            throw runtime_error("invalid answer indices");

        bool okA = (p[A] == 0 || p[A] == N - 1);
        bool okB = (p[B] == 0 || p[B] == N - 1);

        if (!(okA && okB)) {
            throw runtime_error("wrong answer");
        }

        if (number_queries > 30) {
            throw runtime_error("too many queries");
        }

        cout << "Correct! Used " << number_queries << " queries\n";
#endif

#ifdef EVAL
        cout << "! " << A << " " << B << endl;
        cout.flush();
#endif
    }
};

Jury jury;
int n;

signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    jury.read();
    n = jury.N;

    int X = 0;
    for (int bit = 0; (1LL << bit) < n; ++bit) {
        string qry(n, '0');
        for (int j = 0; j < n; ++j) {
            if ((j & (1LL << bit)))
                qry[j] = '1';
        }

        int res = jury.query(qry);
        if (res % 2 == 1)
            X |= (1LL << bit);
    }

    int lo = 0, hi = n - 1, pos1 = -1;
    while (lo <= hi) {
        auto mid = (lo + hi) >> 1;

        string qry(n, '0');
        for (int i = lo; i <= mid; ++i) {
            if ((i ^ X) > i)
                qry[i] = '1';
        }

        int res = jury.query(qry);
        if (res % 2 == 1) {
            pos1 = mid;
            hi = mid - 1;
        }
        else
            lo = mid + 1;
    }

    int pos2 = (X ^ pos1);
    jury.submit(pos1, pos2);
    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...