QOJ.ac

QOJ

Time Limit: 0.5 s Memory Limit: 1024 MB Total points: 100 Interactive

# 5015. 树

Statistics

题目背景

小G出了一个签到题,但被小F随手加强了……

题目描述

这是一道交互题。

有一棵 $n$ ($n≤1\,000$) 个节点的树,所有边权值为 $1$,但你不知道哪两个点之间存在边。

但是你可以查询一个点到一个集合的距离和来寻找隐藏的边。

具体来说你可以使用 $ask(u,V)$ 其中 $V$ 是一个集合(元素两两不同),返回值为 $∑_{x∈V}dist(u,x)$, 其中 $dist(x,y)$ 为树上 $x,y$ 两点最短路的长度。你需要通过 $answer(u,v)$ 来回答找到的所有边。

但询问的次数不能超过 $A$ 次,且 $|V|$ 的总和不能超过 $B$。

实现细节

本题仅支持符合 C++ 11 标准及以上的 C++ 语言。

你需要在代码开头包含 :

#include "tree.h"

你不需要实现主函数,你只需实现如下函数:

void solver(int n, int A, int B)

该函数会在每组测试点开始时调用一次。

你可以调用如下函数不超过 $A$ 次,$v$ 的大小总和不能超过 $B$,同一次调用 $v$ 中元素不能相同:

int ask(int u, vector <int> v)

表示询问点 $u$ 到 $v$ 中所有点距离之和。

得出答案后,你需要调用如下函数恰好 $n−1$ 次:

void answer(int u, int v)

表示存在一条 $(u,v)$ 的树边。

输入在交互开始前已经确定,交互库不自适应。

输入格式

第一行三个整数 $n,A,B$。

接下来 $n−1$ 行每行两个整数 $u,v$ 表示一条树边。

输出格式

若输入格式或询问格式有误,则会输出 Invalid,并告知错误原因。

若询问次数超过 $A$,则会输出 Too many queries

若询问的集合 $v$ 的大小总和超过 $B$,则会输出 The sum is too large

若返回的边错误,则会输出 Different tree

若答案正确,则会输出Correct cnt=x sum=y,其中 $x$ 为询问总次数,$y$ 为 $v$ 的大小总和。

样例数据

样例输入

3 114 514
1 2
2 3

样例输出

Correct cnt=2 sum=3

交互过程

tree.cpp : ask(1,{2,3})
grader.cpp : 3
tree.cpp : ask(1,{2})
grader.cpp : 1
tree.cpp : answer(1,2)
tree.cpp : answer(2,3)
grader.cpp : Correct cnt=2 sum=3

数据范围

Subtask 1 (3分) : $n≤1\,000,A=5×10^5,B=5×10^5$。

Subtask 2 (17分) : $n≤100,A=3×10^3,B=3×10^4$

Subtask 3 (20分) : $n≤1\,000,A=5×10^4,B=3×10^6$。

Subtask 4 (60分) : $n≤1\,000,A=8\,500,B=3×10^5$。

交互库使用的时间和内存很少,可以忽略。