QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#728320#9570. Binary Treeucup-team5657#TL 0ms0kbC++143.6kb2024-11-09 14:58:102024-11-09 14:58:20

Judging History

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

  • [2024-11-09 14:58:20]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-11-09 14:58:10]
  • 提交

answer

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

typedef long long ll;

const int N = 1e5 + 5;
const int B = 19;

struct edge {
	int to, Next;

	edge() {}
	edge(int to, int Next): to(to), Next(Next) {}
} G[N << 1];

int head[N], cnt;

inline void add_edge(int u, int v) {
	G[++cnt] = edge(v, head[u]);
	head[u] = cnt;
}

int T, n;

vector <int> V, tmp1;
vector <pair <int, int> > E, tmp2;

int fa[N], dep[N], dfn[N], dcnt;
pair <int, int> f[B][N];

inline void dfs0(int u) {
	dep[u] = dep[fa[u]] + 1;
	dfn[u] = ++dcnt;
	for (int i = head[u]; i; i = G[i].Next) {
		int v = G[i].to;
		if (v == fa[u]) {
			continue;
		}
		fa[v] = u;
		dfs0(v);
	}
}

inline void init() {
	dcnt = 0;
	dfs0(1);
	for (int i = 1; i <= n; ++i) {
		f[0][dfn[i]] = make_pair(dep[i], i);
	}
	for (int j = 1; j < B; ++j) {
		for (int i = 1; i + (1 << j) - 1 <= n; ++i) {
			f[j][i] = min(f[j - 1][i], f[j - 1][i + (1 << (j - 1))]);
		}
	}
}

inline int ask(int u, int v) {
	cout << "? " << u << " " << v << endl;
	int res;
	cin >> res;
	return res;
}

inline void print(int u) {
	cout << "! " << u << endl;
}

ll siz[N], g[N];

inline void dfs1(int fa, int u) {
	siz[u] = 1;
	for (int i = head[u]; i; i = G[i].Next) {
		int v = G[i].to;
		if (v == fa) {
			continue;
		}
		dfs1(u, v);
		siz[u] += siz[v];
		g[u] += g[v] + siz[v];
	}
}

inline void dfs2(int fa, int u) {
	if (fa) {
		g[u] = g[fa] - siz[u] + (V.size() - siz[u]);
	}
	for (int i = head[u]; i; i = G[i].Next) {
		int v = G[i].to;
		if (v == fa) {
			continue;
		}
		dfs2(u, v);
	}
}

inline int lca(int u, int v) {
	if (u == v) {
		return u;
	}
	if (dfn[u] > dfn[v]) {
		swap(u, v);
	}
	int d = __builtin_clz(dfn[v] - dfn[u]) ^ 31;
	int p = min(f[d][dfn[u] + 1], f[d][dfn[v] - (1 << d) + 1]).second;
	return fa[p];
}

inline int dis(int u, int v) {
	return dep[u] + dep[v] - (dep[lca(u, v)] << 1);
}

inline int F() {
	if (V.size() == 1) {
		return V[0];
	}
	for (auto u: V) {
		head[u] = 0;
	}
	cnt = 0;
	for (auto p: E) {
		add_edge(p.first, p.second);
		add_edge(p.second, p.first);
	}
	dfs1(0, V[0]);
	dfs2(0, V[0]);
	int u = -1;
	for (auto p: V) {
		if (u == -1 || g[p] <= g[u]) {
			u = p;
		}
	}
	int p = G[head[u]].to, q = G[G[head[u]].Next].to;
	if (!q) {
		q = u;
	}
	int res = ask(p, q);
	tmp1 = V;
	tmp2 = E;
	V.clear();
	E.clear();
	if (res == 0) {
		for (auto u: tmp1) {
			if (dis(u, p) < dis(u, q)) {
				V.emplace_back(u);
			}
		}
		for (auto k: tmp2) {
			if (dis(k.first, p) < dis(k.first, q) && dis(k.second, p) < dis(k.second, q)) {
				E.emplace_back(k);
			}
		}
	} else if (res == 1) {
		for (auto u: tmp1) {
			if (dis(u, p) == dis(u, q)) {
				V.emplace_back(u);
			}
		}
		for (auto k: tmp2) {
			if (dis(k.first, p) == dis(k.first, q) && dis(k.second, p) == dis(k.second, q)) {
				E.emplace_back(k);
			}
		}
	} else {
		for (auto u: tmp1) {
			if (dis(u, p) > dis(u, q)) {
				V.emplace_back(u);
			}
		}
		for (auto k: tmp2) {
			if (dis(k.first, p) > dis(k.first, q) && dis(k.second, p) > dis(k.second, q)) {
				E.emplace_back(k);
			}
		}
	}
	return F();
}

inline void solve() {
	cin >> n;
	for (int i = 1; i <= n; ++i) {
		head[i] = 0;
	}
	cnt = 0;
	for (int i = 1; i <= n; ++i) {
		int u, v;
		cin >> u >> v;
		V.emplace_back(i);
		if (u) {
			E.emplace_back(make_pair(i, u));
			add_edge(i, u);
			add_edge(u, i);
		}
		if (v) {
			E.emplace_back(make_pair(i, v));
			add_edge(i, v);
			add_edge(v, i);
		}
	}
	init();
	print(F());
}

int main() {
	cin >> T;
	while (T--) {
		solve();
	}
	return 0;
}

詳細信息

Test #1:

score: 0
Time Limit Exceeded

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
? 0 1

result: