QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#735794#9570. Binary TreedodolaML 1ms3840kbC++234.0kb2024-11-11 21:42:512024-11-11 21:42:52

Judging History

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

  • [2024-11-11 21:42:52]
  • 评测
  • 测评结果:ML
  • 用时:1ms
  • 内存:3840kb
  • [2024-11-11 21:42:51]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

typedef double ld;
typedef unsigned long ul;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> pll;

const int maxn = 3e6 + 50;
const int inf = 0x3f3f3f;
const ll mo998 = 998244353;

vector<bool> isprime;
vector<ll> primes;
void init_primes() {
  isprime.assign(maxn + 1, true);
  isprime[0] = isprime[1] = false;
  for (ll i = 2; i <= maxn; i++) {
    if (!isprime[i])
      continue;
    for (ll j = 2; i * j <= maxn; j++) {
      isprime[i * j] = false;
    }
  }
}

vector<map<ll, bool>> tree;
map<ll, ll> siz, weight;
ll n;
ll centroid[2];
void GetCentroid(ll cur, ll fa) {
  siz[cur] = 1;
  weight[cur] = 0;
  for (auto [t, b] : tree[cur]) {
    if (t != fa && b) {
      GetCentroid(t, cur);
      siz[cur] += siz[t];
      weight[cur] = max(weight[cur], siz[t]);
    }
  }
  weight[cur] = max(weight[cur], n - siz[cur]);
  if (weight[cur] <= n / 2) {
    centroid[centroid[0] != 0] = cur;
  }
}

ll cnt;
void dfs(ll u, ll fa) {
  cnt++;
  for (auto [t, b] : tree[u]) {
    if (t == fa || !b)
      continue;
    dfs(t, u);
  }
}

void solve() {
  ll nx;
  cin >> nx;
  n = nx;

  tree.assign(nx + 1, map<ll, bool>());

  for (int i = 1; i <= nx; i++) {
    ll x, y;
    cin >> x >> y;
    if (x) {
      tree[i][x] = true;
      tree[x][i] = true;
    }
    if (y) {
      tree[i][y] = true;
      tree[y][i] = true;
    }
  }

  ll t;

  auto ask = [&](ll u, ll v) {
    cout << "? " << u << ' ' << v << endl;
    cin >> t;
  };
  auto conf = [&](ll s) { cout << "! " << s << endl; };

  ll u = 1, v, w;
  while (true) {

    siz.clear(), weight.clear();

    centroid[0] = centroid[1] = 0;
    GetCentroid(u, -1);

    if (centroid[0] && centroid[1]) {
      // 两个重心
      u = centroid[0], v = centroid[1];
      ask(u, v);

      if (t == 2) {
        // v比较近
        swap(u, v);
      }

      cnt = 0ll;
      dfs(v, u);
      n -= cnt;

      tree[u][v] = false;

    } else {
      ll s = centroid[0];
      ll tree_size = 0ll;
      for (auto [i, b] : tree[s]) {
        if (b)
          tree_size++;
      }
      if (tree_size == 2) {
        u = v = -1;
        for (auto [x, b] : tree[s]) {
          if (!b)
            continue;
          if (u == -1) {
            u = x;
          } else if (v == -1) {
            v = x;
          }
        }
        ask(u, v);

        if (t == 1) {
          conf(s);
          return;
        }

        if (t == 2) {
          swap(u, v);
        }

        // u比较近
        cnt = 0ll;
        dfs(s, u);
        n -= cnt;

        tree[u][s] = false;

      } else if (tree_size == 3) {
        u = v = w = -1;
        for (auto [x, b] : tree[s]) {
          if (!b)
            continue;
          if (u == -1) {
            u = x;
          } else if (v == -1) {
            v = x;
          } else {
            w = x;
          }
        }

        ask(u, v);
        if (t == 0) {
          tree[u][s] = false;
          cnt = 0ll;
          dfs(s, u);
          n -= cnt;

        } else if (t == 1) {
          tree[s][u] = false;
          tree[s][v] = false;

          cnt = 0ll;
          dfs(u, s);
          n -= cnt;
          cnt = 0ll;
          dfs(v, s);
          n -= cnt;

          u = s;
        } else if (t == 2) {
          tree[v][s] = false;

          cnt = 0ll;
          dfs(s, v);
          n -= cnt;

          u = v;
        }

      } else {
        u = s, v = tree[s].begin()->first;
        ask(u, v);
        if (t == 0) {
          conf(u);
          return;
        }
        if (t == 2) {
          conf(v);
          return;
        }
      }
    }

    if (n == 1) {
      conf(u);
      return;
    }
  }
}

void init() {
  // init_primes();
}

int main(void) {
  // ios::sync_with_stdio(false);
  // cin.tie(0);
  init();
  int _t = 1;
  cin >> _t;
  cin.get();
  while (_t--)
    solve();

  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

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

output:

? 1 3
? 4 3
! 4
? 2 1
! 1

result:

ok OK (2 test cases)

Test #2:

score: -100
Memory Limit Exceeded

input:

5555
8
2 0
8 6
0 0
3 0
0 0
7 0
0 0
5 4
2
0
2
8
0 0
1 4
2 0
0 0
7 8
0 0
3 0
6 0
0
2
0
8
5 8
0 0
1 7
0 0
0 0
4 2
0 0
6 0
0
1
0
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
2
5
3 0
5 1
0 0
0 0
4 0
2
0
5
5 0
0 0
0 0
3 0
2 4
1
2
3
3 0
1 0
0 0
2
2
2 0
0 0
0
3
2 3
0 0
0 0
0
10
2 8
9 7
0 0
...

output:

? 8 2
? 6 2
? 7 6
! 6
? 7 3
? 8 5
? 7 5
! 7
? 8 1
? 2 4
? 8 6
! 8
? 2 4
? 3 2
! 2
? 5 6
? 1 4
! 4
? 1 5
? 4 5
! 4
? 1 2
? 3 5
! 5
? 2 3
! 3
? 2 1
! 2
? 2 3
! 2
? 7 2
? 1 9
? 8 1
! 8
? 2 1
! 1
? 5 9
? 2 9
? 1 9
! 9
? 10 5
? 1 5
? 3 9
! 7
? 3 4
? 1 7
? 2 8
! 2
? 2 1
! 2
? 3 4
? 1 7
! 7
? 4 5
? 8 2
? 3...

result: