QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#742801#9570. Binary Treelmx111TL 1ms5716kbC++203.1kb2024-11-13 17:21:042024-11-13 17:21:13

Judging History

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

  • [2024-11-13 17:21:13]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:5716kb
  • [2024-11-13 17:21:04]
  • 提交

answer

#include <bits/stdc++.h>
#define int int64_t

// const char endl = '\n';
using std::endl;

const int maxn = (int)1.1E5;

int son[2][maxn], fa[maxn], sz[maxn], weight[maxn];

int num_now;
int center;

void dfs(int u) {
  sz[u] = 1;
  weight[u] = 0;
  for (int i = 0; i < 2; ++i) {
    if (son[i][u]) {
      dfs(son[i][u]);
      sz[u] += sz[son[i][u]];
      weight[u] = std::max(weight[u], sz[son[i][u]]);
    }
  }
  weight[u] = std::max(weight[u], num_now - sz[u]);
  if (center) return;
  if (weight[u] <= num_now / 2) center = u;
  // std::cout << "u: " << u << endl;
}

void solve() {
  int n;
  std::cin >> n;
  for (int i = 0; i <= n + 5; ++i) son[0][i] = son[1][i] = fa[i] = 0;
  for (int i = 1, x, y; i <= n; ++i) {
    std::cin >> x >> y;
    fa[son[0][i] = x] = fa[son[1][i] = y] = i;
  }
  int root = 0;
  for (int i = 1; i <= n; ++i)
    if (fa[i] == 0) root = i;
  int q = log2(n);
  int t;
  num_now = n;
  for (int j = 1; j <= q; ++j) {
    if (num_now == 1) {
      std::cout << "! " << root << endl;
      return;
    }
    center = 0;
    dfs(root);
    // std::cout << "center: " << center << endl;
    if (num_now == 2) {
      std::cout << "? " << center << ' ' << root << endl;
      std::cin >> t;
      if (t)
        std::cout << "! " << root << endl;
      else
        std::cout << "! " << center << endl;
      return;
    }
    int f = fa[center], ls = son[0][center], rs = son[1][center];
    int sz1 = num_now - sz[center];
    int minsz = std::min(sz1, std::min(sz[ls], sz[rs]));
    if (minsz == sz1) {
      std::cout << "? " << ls << ' ' << rs << endl;
      std::cin >> t;
      if (t == 0) {
        root = ls;
        num_now = sz[ls];
      }
      if (t == 2) {
        root = rs;
        num_now = sz[rs];
      }
      if (t == 1) {
        son[0][center] = son[1][center] = 0;
        num_now -= sz[ls] + sz[rs];
      }
    } else if (minsz == sz[ls]) {
      std::cout << "? " << f << ' ' << rs << endl;
      std::cin >> t;
      if (t == 0) {
        num_now -= sz[center];
        if (son[0][f] == center)
          son[0][f] = 0;
        else
          son[1][f] = 0;
      }
      if (t == 1) {
        root = center;
        num_now = sz[center] - sz[rs];
        son[1][center] = 0;
      }
      if (t == 2) {
        root = rs;
        num_now = sz[rs];
      }
    } else if (minsz == sz[rs]) {
      std::cout << "? " << f << ' ' << ls << endl;
      std::cin >> t;
      if (t == 0) {
        num_now -= sz[center];
        if (son[0][f] == center)
          son[0][f] = 0;
        else
          son[1][f] = 0;
      }
      if (t == 1) {
        root = center;
        num_now = sz[center] - sz[ls];
        son[0][center] = 0;
      }
      if (t == 2) {
        root = ls;
        num_now = sz[ls];
      }
    }
  }
}
int32_t main() {
#ifndef _DEBUG
  // std::ios::sync_with_stdio(false);
  // std::cin.tie(nullptr);
#endif
  int tc = 1;
  std::cin >> tc;
  while (tc--) solve();
#ifdef _DEBUG
  std::cout << std::endl;
  std::cout << "Time used: " << clock() << "ms" << std::endl;
  system("pause");
  return 0;
#endif
}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 5716kb

input:

2
5
0 0
1 5
2 4
0 0
0 0
1
0
2
0 2
0 0
2

output:

? 3 5
? 1 2
! 1
? 2 1
! 1

result:

ok OK (2 test cases)

Test #2:

score: -100
Time Limit Exceeded

input:

5555
8
2 0
8 6
0 0
3 0
0 0
7 0
0 0
5 4
0
0
2
8
0 0
1 4
2 0
0 0
7 8
0 0
3 0
6 0
0
0
0
8
5 8
0 0
1 7
0 0
0 0
4 2
0 0
6 0
0
0
2
5
4 5
3 1
0 0
0 0
0 0
0
2
8
0 0
0 0
5 6
0 0
1 4
2 0
3 8
0 0
0
0
5
3 0
5 1
0 0
0 0
4 0
0
2
5
5 0
0 0
0 0
3 0
2 4
1
0
3
3 0
1 0
0 0
2

output:

? 2 4
? 2 7
? 2 1
! 1
? 7 2
? 5 6
? 7 5
! 7
? 1 6
? 3 5
? 7 3
! 3
? 2 5
? 3 2
! 2
? 5 6
? 1 4
! 1
? 5 1
? 4 5
! 5
? 2 4
? 5 1
! 5
? 2 3

result: