#P3839. [IOI2017] The Big Prize

[IOI2017] The Big Prize

题目背景

这里是洛谷。如果有疑问,可以发帖求助。

如果你习惯于写函数式交互,以下内容可能对你有帮助:

vector<int>ask(int i)
{
	printf("? %d\n",i);fflush(stdout);
	vector<int>ret(2);
	scanf("%d%d",&ret[0],&ret[1]);
	return ret;
}
int find_best(int n)
{
	//
}
main()
{
	int n;scanf("%d",&n);
	printf("! %d\n",find_best(n));
}

无论如何,你都不应引入额外的头文件。

题目描述

“大奖”是一个家喻户晓的 TV 游戏节目。这次你很幸运地进入到最后一轮。已知编号从 00n1n-1nn 个盒子从左到右排成一行,你就站在这排盒子的前面。每个盒子里面放有一个奖品,必须打开盒子才能看到是什么奖品。已知有 v5v\leq5 种不同类型的奖品。这 vv 种类型按照奖品价值的降序从 11vv 排列。

类型 11 的奖品是一块钻石,价值最高。所有盒子加起来刚好只有一块钻石。类型 vv 的奖品是一块棒棒糖,价值最低。为使得游戏更加激动人心,相对便宜的奖品数量远比价值昂贵的奖品数量要多。更具体一点,对于满足 2tv2\leq t \leq v 的所有 tt,我们有: 如果类型 t1t-1 的奖品有 kk 个,那么类型 tt 的奖品将严格多于 k2k^2 个。

你的目标是赢得那块钻石。在游戏结束时,你必须打开一个盒子并收取盒子内的奖品。在选择要打开的盒子之前,你可以向节目主持人 Rambod 提一些问题。在每一个问题中,你选择就某个 ii 号盒子进行提问。Rambod 将给你一个包含两个整数的数组 aa 作为回答。这两个整数的意义如下:

  • ii 号盒子左面的盒子中,刚好有 a[0]a[0] 个盒子中的奖品,价值比 ii 号盒子中的奖品价值要高。
  • ii 号盒子右面的盒子中,刚好有 a[1]a[1] 个盒子中的奖品,价值比 ii 号盒子中的奖品价值要高。

例如,假设 n=8n=8,在你的问题中,你选择就 i=2i=2 号盒子进行提问。Rambod 的回答是 a=[1,2]a=[1,2]。这个回答的意义是:

  • 00 号盒子和 11 号盒子中恰好有一个盒子中的奖品比 ii 号盒子中的奖品更贵。
  • 3,4,,73,4,\cdots,7 号盒子中恰好有 22 个盒子中的奖品比 22 号盒子中的奖品更贵。

你的任务就是通过问少量的问题找出包含钻石的盒子。

输入格式

你的程序开始运行时,应当读入一个正整数 nn

你可以按以下格式发起询问:

  • ? i
    意为你选择就 ii 号盒子进行提问。你需要保证 0i<n0\leq i<n
    随后你应当读入两个整数 a[0] a[1],是交互库对你的回答。

你可以按以下格式报告答案:

  • ! i
    意为你确定 ii 号盒子内有钻石。
    随后你应当立刻结束你的程序。

输出格式

在发起询问后,不要忘记刷新缓冲区。你可以使用:

  • fflush(stdout) or cout.flush() in C++;
  • stdout.flush() in Python;
  • 对于其他语言,参阅其文档。
8

0 3

0 1

1 2

0 0

2 1

2 1

1 0

3 0

? 0

? 1

? 2

? 3

? 4

? 5

? 6

? 7

! 3

提示

样例解释

8
3 2 3 1 3 3 2 3

上图阐释了这个例子。图中上半部分给出了每个盒子中奖品的类型。图中的下半部分阐释了询问 ? 2

限制

  • 3n2000003\leq n \leq200000.
  • 每个盒子中奖品的类型介于 11vv 之间(含)。
  • 类型 11 的奖品恰有一个。
  • 对于所有 2tv2\leq t \leq v,如果类型 t1t-1 的奖品有 kk 个,那么类型 tt 的奖品将严格多于 k2k^2 个。

子任务与评分

  1. 2020 分)恰好有 11 个钻石和 n1n-1 个棒棒糖 (所以,v=2v=2)。你可以询问最多 1000010000 次。
  2. 8080 分)没有附加限制。

在子任务 2 中你可以获得部分分。令 qq 是在这个子任务的所有测试数据上发起询问的最大次数,那么你在这个子任务上的得分将按照下表计算: