Doremy‘s Perfect DS Class (Hard Version)

题目描述

The only difference between this problem and the other two versions is the maximum number of queries. In this version, you are allowed to ask at most \mathbf{20}20 queries. You can make hacks only if all versions of the problem are solved.

This is an interactive problem.

"Everybody! Doremy's Perfect Data Structure Class is about to start! Come and do your best if you want to have as much IQ as me!" In today's Data Structure class, Doremy is teaching everyone a powerful data structure — Doremy tree! Now she gives you a quiz to prove that you are paying attention in class.

Given an array aa of length mm , Doremy tree supports the query Q(l,r,k)Q(l,r,k) , where 1 \leq l \leq r \leq m1≤l≤r≤m and 1 \leq k \leq m1≤k≤m , which returns the number of distinct integers in the array \left[\lfloor\frac{a_l}{k} \rfloor, \lfloor\frac{a_{l+1}}{k} \rfloor, \ldots, \lfloor\frac{a_r}{k} \rfloor\right][⌊kal​​⌋,⌊kal+1​​⌋,…,⌊kar​​⌋] .

Doremy has a secret permutation pp of integers from 11 to nn . You can make queries, in one query, you give 33 integers l,r,kl,r,k ( 1 \leq l \leq r \leq n1≤l≤r≤n , 1 \leq k \leq n1≤k≤n ) and receive the value of Q(l,r,k)Q(l,r,k) for the array pp . Can you find the index yy ( 1 \leq y \leq n1≤y≤n ) such that p_y=1py​=1 in at most \mathbf{20}20 queries?

Note that the permutation pp is fixed before any queries are made.

输入格式

输出格式

You begin the interaction by reading an integer nn ( 3 \le n \le 10243≤n≤1024 ) in the first line — the length of the permutation.

To make a query, you should output

  • "? l\ r\ kl r k " ( 1 \leq l \leq r \leq n1≤l≤r≤n , 1 \leq k \leq n1≤k≤n )

in a separate line. After each query, you should read an integer xx — the value of Q(l,r,k)Q(l,r,k) for pp . In this version of the problem, you can make at most 2020 such queries.To give the answer, you should output

  • "! yy " ( 1 \leq y \leq n1≤y≤n )

in a separate line, where p_y=1py​=1 .After printing a query or the answer, do not forget to output the end of line and flush the output. Otherwise, you will get Idleness limit exceeded. To do this, use:

  • fflush(stdout) or cout.flush() in C++;
  • System.out.flush() in Java;
  • flush(output) in Pascal;
  • stdout.flush() in Python;
  • see documentation for other languages.

Hacks Format

The first line of the hack contains an integer nn ( 3 \le n \le 10243≤n≤1024 ) — the length of the permutation.

The second line of the hack contains nn distinct integers p_1,p_2,\ldots,p_np1​,p2​,…,pn​ ( 1 \le p_i\le n1≤pi​≤n ) — the permutation.

题意翻译

  • 这是一道交互题。
  • 交互库有一个 [1,n][1,n] 的排列 pp。
  • 你可以询问 l,r,kl,r,k,交互库会返回 \left\lfloor\dfrac{p_l}k\right\rfloor,\left\lfloor\dfrac{p_{l+1}}k\right\rfloor,\cdots,\left\lfloor\dfrac{p_r}k\right\rfloor⌊kpl​​⌋,⌊kpl+1​​⌋,⋯,⌊kpr​​⌋ 中不同数的个数。
  • 你需要在 2020 次询问内找到 pp 中 11 的位置。
  • n\in[3,1024]n∈[3,1024]。

输入输出样例

输入 #1复制

5

2

2

1

3

输出 #1复制

? 1 3 4

? 3 5 3

? 3 4 5

? 3 5 2

! 4

说明/提示

The permutation in the example is [3,5,2,1,4][3,5,2,1,4] .

The input and output for example illustrate possible interaction on that test (empty lines are inserted only for clarity).

In this interaction process:

  • For the first query, \lfloor\frac{3}{4}\rfloor=0,\lfloor\frac{5}{4}\rfloor=1,\lfloor\frac{2}{4}\rfloor=0⌊43​⌋=0,⌊45​⌋=1,⌊42​⌋=0 , so the answer is 22 .
  • For the second query, \lfloor\frac{2}{3}\rfloor=0,\lfloor\frac{1}{3}\rfloor=0,\lfloor\frac{4}{3}\rfloor=1⌊32​⌋=0,⌊31​⌋=0,⌊34​⌋=1 , so the answer is still 22 .
  • For the third query, \lfloor\frac{2}{5}\rfloor=0,\lfloor\frac{1}{5}\rfloor=0⌊52​⌋=0,⌊51​⌋=0 , so the answer is 11 .
  • For the fourth query, \lfloor\frac{2}{2}\rfloor=1,\lfloor\frac{1}{2}\rfloor=0,\lfloor\frac{4}{2}\rfloor=2⌊22​⌋=1,⌊21​⌋=0,⌊24​⌋=2 , so the answer is 33 .

The correct answer is got after 44 queries, so this process will be judged correct.

 

这种题目一般都考虑从较特殊的 k = 2k=2 或 k = nk=n 入手。k = nk=n 看起来不太可行,因此考虑 k = 2k=2。

从 3030 次询问限制可以想到二分。设 \mathrm{solve}(l, r)solve(l,r) 表示已知答案 a \in [l, r]a∈[l,r],希望确定答案。设 m = \frac {l + r} 2m=2l+r​。

关键问题在于确定答案究竟在 [l, m][l,m] 还是 [m + 1, r][m+1,r] 中。这里有个有趣的思想,就是我们不能将眼光仅局限于 [l, r][l,r],因为 \mathrm{solve}(l, r)solve(l,r) 并不是一个严格的子问题,l\sim rl∼r 并不是 1\sim r - l + 11∼r−l+1 的排列,我们依然需要依靠 p_1\sim p_np1​∼pn​。换言之,我们只需要确定答案在 [1, m][1,m] 或 [m + 1, r][m+1,r] 中。

根据这样的思想,考虑如何询问。

将 p_ipi​ 全部除以 22 下取整,称 x, yx,y 配对当且仅当 p_x, p_ypx​,py​ 除以 22 下取整相同。

当 nn 为奇数时,除了 aa 以外的所有位置均有与其配对的位置,而询问 Q(l, r, 2)Q(l,r,2) 相当于求出 r - l + 1r−l+1 减去区间配对数,则区间落单数可由 r - l + 1r−l+1 减去两倍区间配对数得到,即 2Q(l, r, 2) - (r - l + 1)2Q(l,r,2)−(r−l+1)。设 f(l, r)f(l,r) 表示 [l, r][l,r] 的区间落单数,则对于 f(1, m)f(1,m) 和 f(m + 1, n)f(m+1,n),因为每个除了 aa 以外的区间落单位置会同时在 [1, m][1,m] 和 [m + 1, n][m+1,n] 中出现,所以只需递归进入 ff 较大的那个区间即可。时间复杂度询问次数 2\lceil\log_2 n\rceil \leq 202⌈log2​n⌉≤20。

当 nn 为偶数时,设 p_b = npb​=n,则 a, ba,b 均没有与其配对的位置。类似地,求出 f(1, m)f(1,m) 和 f(m + 1, n)f(m+1,n)。若已知 b\leq mb≤m 或 b > mb>m,则扣除 bb 的贡献后类似 nn 为奇数做。否则,若 f(1, m) > f(m + 1, n)f(1,m)>f(m+1,n),说明 a, b\leq ma,b≤m。若 f(1, m) < f(m + 1, n)f(1,m)<f(m+1,n),说明 a, b > ma,b>m。若 f(1, m) = f(m + 1, n)f(1,m)=f(m+1,n),说明 a, ba,b 在 mm 的两侧。

考虑确定 bb 的位置。注意到将所有数除以 nn 下取整之后,只有 p_b = 1pb​=1,其它均为 00。利用这一点,我们断言若 r - l + 1 \geq 2r−l+1≥2,则 b\in [l, r]b∈[l,r] 当且仅当 Q(l, r, n) = 2Q(l,r,n)=2。因此,若 m > 1m>1,可直接询问 Q(1, m, n)Q(1,m,n) 确定 bb 是否在 [1, m][1,m] 中。否则 m = 1m=1,因为 n\geq 3n≥3,所以询问 Q(m + 1, n, n)Q(m+1,n,n) 确定 bb 是否在 [m + 1, n][m+1,n] 中。

确定 bb 的位置后,因我们向相反方向递归,所以若此时 b\leq mb≤m 则接下来一定有 b\leq m'b≤m′,若此时 b > mb>m 则接下来一定有 b > m'b>m′。询问次数 2\lceil\log_2 n\rceil + 1 \leq 212⌈log2​n⌉+1≤21,可以通过 G2。

最后优化通常是通过已知信息简少询问次数。

考虑到卡满 \lceil \log_2 n\rceil⌈log2​n⌉ 上界的二分过程必然经过 r - l + 1 = 2r−l+1=2 的情形。当 l \neq 1l=1 时,我们必然询问过 Q(1, l - 1, 2)Q(1,l−1,2),否则 Q(1, l - 1, 2) = 0Q(1,l−1,2)=0。当 r\neq nr=n 时,我们必然询问过 Q(1, r, 2)Q(1,r,2),否则 Q(1, r, 2) = \lfloor \frac n 2\rfloor + 1Q(1,r,2)=⌊2n​⌋+1。对于 Q(l, n, 2), Q(r + 1, n, 2)Q(l,n,2),Q(r+1,n,2) 同理。

考虑 [l, r][l,r] 中不是 aa 的位置 xx。我们容易根据此时是否确定 bb 来判断 xx 是否等于 bb。若 x = bx=b,则直接进入判断 bb 的位置的分支,只需花掉一次询问。若 x\neq bx=b,则考虑与 xx 配对的位置,若与 xx 配对的位置 < l<l,则 Q(1, r, 2) - Q(1, l - 1, 2) = 1Q(1,r,2)−Q(1,l−1,2)=1 且 Q(l, n, 2) - Q(r + 1, n, 2) = 2Q(l,n,2)−Q(r+1,n,2)=2。若与 xx 配对的位置 > r>r,则情况相反,不再赘述。

基于此,不妨设与 xx 配对的位置 < l<l,则若 Q(1, l, 2) = Q(1, l - 1, 2)Q(1,l,2)=Q(1,l−1,2),说明 x = lx=l,a = ra=r,否则说明 x = rx=r,a = la=l。同样只需花掉一次询问。

综上,我们在 r - l + 1 = 2r−l+1=2 的分支少花掉了一次询问,询问次数 2(\lceil \log_2 n\rceil - 1) + 1 + 1\leq 202(⌈log2​n⌉−1)+1+1≤20。代码

 

  • 35
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值