loj#P4751. 「eJOI2024」霍拉舞

「eJOI2024」霍拉舞

注意事项

在 LibreOJ 上,由于语言限制,目前只支持以下语言的提交:

  • C++(标准为 C++ 17 及以上)

请在提交源代码前添加 #include "hora.h"

题目描述

题目译自 eJOI2024 Day2 T3. Hora

这是一个交互题 。

霍拉舞(Hora)是一种传统的罗马尼亚和摩尔多瓦的民间舞蹈,参与者手拉手形成一个大圈……

在第八届欧洲青少年信息学奥林匹克比赛上,有 NN 名参与者开始跳霍拉舞,其中 NN 是一个正偶数。男孩和女孩的数量相等。组织者为霍拉舞中的每个参与者分配了一个环形编号。编号从 00 开始,按顺序依次递增 11,直到 N1N-1。这意味着编号为 00N1N-1 的参与者是邻居,并且每个参与者的编号比其前一个邻居的编号大一。

你不知道哪些参与者是女孩,哪些参与者是男孩,因为你现在正在参加比赛!不过,你可以发起若干次询问。每次询问包含两个整数 LLRR,满足 0L<N0 \leq L<N0R<N0 \leq R<N。交互器将会给出一个整数,表示环上从 LLRR 的连续区间中的男孩数量。具体来说:

  • 如果 LRL \leq R,表示环上编号为 L,L+1,,R1,RL, L+1, \ldots, R-1, R 的参与者的连续区间。
  • 如果 R<LR<L,表示环上编号为 L,L+1N1,0R1,RL, L+1 \ldots N-1,0 \ldots R-1, R 的参与者的连续区间。

你给定了一个整数 KK (1KN)(1 \leq K \leq N)。你的任务是在环上找到一个长度为 KK 的连续区间,使得该区间内男孩和女孩的数量差的绝对值最小。更正式地说,你需要实现一个函数,返回一个整数 SS (0S<N)(0 \leq S<N),使得从 SS 开始的长度为 KK 的连续区间在环上所有长度为 KK 的连续区间中,男孩和女孩数量差的绝对值最小。请注意,某些环可能有多个具有相同最小数量差的绝对值的 SS。在这种情况下,你可以返回其中任何一个。

两个数 xxyy 之间的差的绝对值为 xy|x-y|。例如,24=2|2-4|=274=3|7-4|=3

评分程序不是自适应的,即环上的每个参与者性别在开始之前便已经确定了。

实现细节

你需要实现以下函数:

int solve(int N, int K)
  • NN:霍拉舞参与者的数量。
  • KK:考虑的区间的长度。
  • 该函数应返回 SS,表示开始长度为 KK 的区间的整数,且该区间内男孩和女孩数量差的绝对值最小。
  • 该函数只被调用一次。

上述函数可以调用以下函数:

int ask(int L, int R)
  • LL :查询区间的开始编号。
  • RR :查询区间的结束编号。
  • 返回查询区间内的男孩数量。
  • 如果对 ask 函数的调用次数超过 10510^5 次,代码将会被判为 Wrong Answer

样例

假设圈子如下图所示:

请注意,带有白色字母 B 的圆圈代表男孩,带有黑色字母 G 的圆圈代表女孩。此外,每个圆圈右侧的数字表示相应人的编号。

考虑以下调用:

solve(12, 5)

在这个样例中,我们有 1212 个人跳霍拉舞,我们搜索长度为 55 的连续区间,且男孩和女孩数量差的绝对值最小。

程序发起调用:

ask(0, 10)

对应的答案是 66,意味着在这个区间中有 66 个男孩跳霍拉舞。我们可以很容易地推断出同一区间内有 55 个女孩跳霍拉舞。

ask(0, 4)

对应的答案是 44,意味着在这个区间中有 44 个男孩跳霍拉舞。

ask(1, 5)

对应的答案是 33,意味着在这个区间中有 33 个男孩跳霍拉舞。我们可以很容易地推断出同一区间内有 22 个女孩跳霍拉舞。由于 3322 之间的差的绝对值为 11,且不存在更小数量差的绝对值的长度为 55 的区间,因此程序返回 11,这是对应区间的起始位置。

数据范围与提示

对于所有输入数据,满足:

  • 2N1052 \leq N \leq 10^5
  • 1KN1 \leq K \leq N
  • NN 是偶数。
  • 霍拉舞中男孩和女孩的数量相等。

详细子任务附加限制及分值如下表所示。

子任务 分值 附加限制 QfullQ_{full}
11 55 N=34N=34 3434
22 1313 N=105N=10^5,所有男孩相邻,所有女孩也相邻 1818
33 88 N=105N=10^5,每个人的性别是随机生成的 3434
44 1111 N=105,K=50000N=10^5, K=50000 1818
55 1010 N=65536,K=128N=65536, K=128 2626
66 1010 N=105,K=400N=10^5, K=400 2626
77 99 N=105,K=99601N=10^5, K=99601 2626
88 1010 N=105,K=330N=10^5, K=330 6868
99 2424 无附加限制 3434

QQ 为该测试中调用 ask 函数的次数。如果 QQfullQ \leq Q_{full},你将获得该测试点的满分。如果 NQ>QfullN \geq Q>Q_{full},你将获得 $score \cdot \left(1-\left(\frac{\left(Q-Q_{full}\right)}{N}\right)^{0.05}\right)$ 的分数。如果 Q>NQ>N 或者你的程序给出的答案是错误的,你将获得 00 分。每个子任务的得分是所有测试点中最低的得分。

调用 ask 函数超过 10510^{5} 次将被判为 Wrong Answer

示例评测程序

示例评测程序按以下格式读取输入:

  • 11 行:NKN\,K
  • 22 行:A[0]A[1]A[N1]A[0]A[1]\ldots A[N-1],其中数组 AA 是一个字符串,表示我们隐藏的参与者圈子。特别地,如果 A[i]=XA[i]=\texttt{X},则对应的参与者是男孩;如果 A[i]=YA[i]=\texttt{Y},则对应的参与者是女孩。

示例评测程序按以下格式输出每个问题:

  • 11 行:?LR?\,L\,R

示例评测程序按以下格式输出每个答案:

  • 11 行:xx

示例评测程序按以下格式输出参赛者的答案:

  • 11 行:!S!\,S

在交互结束时,示例评测程序会输出参赛者调用 ask 函数的次数。