답안 #1052256

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1052256 2024-08-10T12:48:22 Z That_Salamander Minerals (JOI19_minerals) C++17
0 / 100
1 ms 344 KB
#include <bits/stdc++.h>

void Solve(int N);
int Query(int x);

void Answer(int x, int y);

bool inMachine[100005];
int lastRes = 0;

void setInMachine(int i, bool val) {
    if (inMachine[i] != val) {
        lastRes = Query(i);
        inMachine[i] = val;
    }
}

int query() {
    return lastRes;
}

int ans[50000];
int maxAns[50000];

std::vector<int> a, b;

void Solve(int N) {
    std::vector<int> order(2 * N);
    std::iota(order.begin(), order.end(), 1);
    std::mt19937 rng(time(NULL));
    std::shuffle(order.begin(), order.end(), rng);

    for (int i = 1; i <= 2 * N; i++) {
        int prev = query();
        setInMachine(i, true);
        if (prev != query()) {
            a.push_back(i);
        } else {
            maxAns[b.size()] = a.size() - 1;
            b.push_back(i);
        }
    }

    int m = 1;
    while (m < N) {
        for (int i = 0; i < N; i++) {
            setInMachine(a[i], (i & m));
        }

        std::unordered_map<int, int> ansCounts;
        for (int i = 0; i < N; i++) ansCounts[ans[i]]++;

        std::unordered_map<int, int> numIncr, numSame;


        std::vector<int> order(N);
        std::iota(order.begin(), order.end(), 1);
        std::shuffle(order.begin(), order.end(), rng);

        for (int i: order) {
            int totalStart = ansCounts[ans[i]];
            int numChanged = numIncr[ans[i]];
            int numStay = numSame[ans[i]];

            int maxIncr = totalStart / 2;
            int maxStay = totalStart - maxIncr;

            bool incr;
            if (numChanged == maxIncr) {
                incr = false;
            } else if (numStay == maxStay) {
                incr = true;
            } else {
                int tmp = query();
                setInMachine(b[i], !inMachine[b[i]]);
                incr = query() == tmp;
            }

            
            if (incr) {
                numIncr[ans[i]]++;
                ans[i] += m;
            } else {
                numSame[ans[i]]++;
            }
        }

        m <<= 1;
    }

    for (int i = 0; i < N; i++) {
        Answer(b[i], a[ans[i]]);
    }
}

#ifdef LOCAL_TEST
#include <cstdio>
#include <cstdlib>
#include <algorithm>

constexpr int MAX_N = 43000;
constexpr int MAX_CALLS = 1000000;

namespace {

void WrongAnswer(int code) {
  printf("Wrong Answer [%d]\n", code);
  exit(0);
}

int N;
int counterpart[2 * MAX_N + 1];

int num_queries;
int num_kinds;
int on[2 * MAX_N + 1];
int count[2 * MAX_N + 1];

int num_answers;
int answer[2 * MAX_N + 1];

}  // namespace

int Query(int x) {
  if (!(1 <= x && x <= 2 * N)) {
    printf("Query(%d)\n", x);
    WrongAnswer(1);
  }
  if (++num_queries > MAX_CALLS) {
    //WrongAnswer(2);
  }
  const int type = std::min(x, counterpart[x]);
  if (on[x]) {
    --on[x];
    --count[type];
    if (count[type] == 0) {
      --num_kinds;
    }
  } else {
    ++on[x];
    ++count[type];
    if (count[type] == 1) {
      ++num_kinds;
    }
  }
  return num_kinds;
}

void Answer(int a, int b) {
  if (N < 100)
    std::cout << "Answer(" << a << ", " << b << ")" << std::endl;
  if (++num_answers > N) {
    WrongAnswer(6);
  }
  if (!(1 <= a && a <= 2 * N && 1 <= b && b <= 2 * N)) {
    WrongAnswer(3);
  }
  if (answer[a] != 0) {
    WrongAnswer(4);
  }
  answer[a] = b;
  if (answer[b] != 0) {
    WrongAnswer(4);
  }
  answer[b] = a;
  if (!(counterpart[a] == b && counterpart[b] == a)) {
    WrongAnswer(5);
  }
}

int secret_order[100000];

int main() {
  if (scanf("%d", &N) != 1) {
    fprintf(stderr, "Error while reading input\n");
    exit(1);
  }

  for (int i = 0; i < 2 * N; ++i) {
    secret_order[i] = i + 1;
  }

  std::mt19937 rng(0);
  std::shuffle(secret_order, secret_order + 2 * N, rng);

  for (int i = 1; i <= N; ++i) {
    int x, y;
    x = secret_order[2 * i - 2];
    y = secret_order[2 * i - 1];
    /*if (scanf("%d%d", &x, &y) != 2) {
      fprintf(stderr, "Error while reading input\n");
      exit(1);
    }*/
   if (N < 100)
   printf("%d %d\n", x, y);
    counterpart[x] = y;
    counterpart[y] = x;
  }
  Solve(N);
  if (num_answers != N) {
    WrongAnswer(6);
  }
  printf("Accepted: %d\n", num_queries);
  return 0;
}
#endif
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 344 KB Wrong Answer [1]
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 344 KB Wrong Answer [1]
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 344 KB Wrong Answer [1]
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 344 KB Wrong Answer [1]
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 344 KB Wrong Answer [1]
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 344 KB Wrong Answer [1]
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 344 KB Wrong Answer [1]
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 344 KB Wrong Answer [1]
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 344 KB Wrong Answer [1]
2 Halted 0 ms 0 KB -