[CF2152E]E. Monotone Subsequence题解

E. Monotone Subsequence

time limit per test

2 seconds

memory limit per test

1024 megabytes

This is an interactive problem.

Faker is being naughty again. You asked him to create a nice query problem, but he created an interactive problem where he is answering a query instead! Faker hid a permutation from you, and you have to infer some interesting information by interacting with him.

You are given an integer n. Faker hid a hidden permutation∗ p1,p2,…,pn2+1 of length n2+1. Your goal is to find a monotone subsequence (either increasing or decreasing) of the hidden permutation, with length exactly n+1. It can be proved that every permutation of length n2+1 contains a monotone subsequence of length n+1. For more information about the proof, you can check out this Wikipedia page.

To find it, you can make at most n skyscraper queries to the interactor, which is defined as follows:

  • You provide a set of k indices as a strictly increasing sequence: i1,i2,…,ik.
  • The interactor considers the values of the hidden permutation at these indices: pi1,pi2,…,pik.
  • The interactor then returns the indices corresponding to the visible skyscrapers from this set. An index ij is visible if its value pij is greater than the values of all preceding elements in your query, i.e., pij>pim for all 1≤m<j. This is equivalent to finding the indices of the left-to-right maxima of the sequence (pi1,…,pik).

After making at most n queries, you must report a valid monotone subsequence of length exactly n+1.

Note that the permutation p is fixed before any queries are made and does not depend on the queries.

∗A permutation of length m is an array consisting of m distinct integers from 1 to m in arbitrary order. For example, [2,3,1,5,4] is a permutation, but [1,2,2] is not a permutation (2 appears twice in the array), and [1,3,4] is also not a permutation (m=3 but there is 4 in the array).

有道 翻译

这是一个互动的问题。

Faker又淘气了。您要求他创建一个不错的查询问题,但他创建了一个交互式问题,而不是回答查询!Faker向你隐藏了一个排列,你必须通过与他互动来推断一些有趣的信息。

你得到一个整数 n 。Faker隐藏了一个长度为 n2+1 的隐藏排列 ∗ p1,p2,…,pn2+1 。您的目标是找到隐藏排列的单调子序列(递增或递减),长度恰好为 n+1 。可以证明,每一个长度为 n2+1 的排列都包含一个长度为 n+1 的单调子序列。有关证明的更多信息,您可以查看[这个维基百科页面](https://en.wikipedia.org/wiki/Erdos-Szekeres theorem)。

为了找到它,你最多可以对交互器进行 n 次摩天大楼查询,其定义如下:

—您提供一组 k 索引,作为严格递增的序列: i1,i2,…,ik 。

-交互器考虑这些索引处的隐藏排列的值: pi1,pi2,…,pik 。

-交互器然后返回与该集合中可见摩天大楼对应的索引。如果索引 ij 的值 pij 大于查询中前面所有元素的值,即所有 1≤m<j 的值为 pij>pim ,则索引 ij 可见。这相当于找到序列 (pi1,…,pik) 从左到右的最大值的索引。

在执行最多 n 次查询之后,必须报告长度为的有效单调子序列,长度恰好 n+1 。

请注意,排列 p 在进行任何查询之前都是固定的,并且不依赖于查询。

∗ 长度为 m 的排列是由 m 个不同的整数组成的数组,从 1 到 m ,以任意顺序排列。例如, [2,3,1,5,4] 是一个排列,但 [1,2,2] 不是一个排列( 2 在数组中出现了两次), [1,3,4] 也不是一个排列( m=3 但在数组中有 4 )。

Input

Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤5000). The description of the test cases follows.

The first and only line of each test case contains a single integer n (1≤n≤100).

It is guaranteed that the sum of n2+1 over all test cases does not exceed 10001.

有道 翻译

输入** **

每个测试包含多个测试用例。第一行包含测试用例的数量 t ( 1≤t≤5000 )。下面是测试用例的描述。

每个测试用例的第一行也是唯一一行包含单个整数 n ( 1≤n≤100 )。

保证所有测试用例 n2+1 的和不超过 10001 。

Interaction

The interaction for each test case begins by reading the integer n.

To make a query, print a line in the following format:

  • ? ki1i2…ik

where k is the number of indices in your query (1≤k≤n2+1), and i1,…,ik are the indices themselves, satisfying 1≤i1<i2<…<ik≤n2+1. The indices should be presented in sorted order.

In response, the interactor will print a line in the following format:

  • cj1j2…jc

where c is the number of visible skyscrapers from your query (1≤c≤k), and j1,…,jc are their indices, satisfying 1≤j1<j2<…<jc≤n2+1. The indices will be presented in sorted order.

To report your final answer, print a line in the following format:

  • ! s1s2…sn+1

where s1,…,sn+1 are the indices of the elements that form your found monotone subsequence of length n+1, satisfying 1≤s1<s2<…<sn+1≤n2+1. The indices should be presented in sorted order.

Note that answering does not count toward your limit of commands.

After printing the answer, your program should proceed to the next test case or terminate if there are no more.

After printing each query do not forget to output the end of line and flush∗ the output. Otherwise, you will get Idleness limit exceeded verdict.

If, at any interaction step, you read −1 instead of valid data, your solution must exit immediately. This means that your solution will receive Wrong answer because of an invalid query or any other mistake. Failing to exit can result in an arbitrary verdict because your solution will continue to read from a closed stream.

Hacks

To hack, use the following format.

The first line should contain a single integer t (1≤t≤5000).

The first line of each test case should contain a single integer n (1≤n≤100).

The second line of each test case should contain n2+1 space separated integers p1,p2,…,pn2+1 (1≤pi≤n2+1). p should be a permutation of length n2+1.

The sum of n2+1 should not exceed 10001.

For example, the following is the hack format of the example test:

1

∗To flush, use:

  • fflush(stdout) or cout.flush() in C++;
  • sys.stdout.flush() in Python;
  • see the documentation for other languages.

有道 翻译

** **进行交互

每个测试用例的交互从读取整数 n 开始。

要执行查询,请以以下格式打印一行:

            • ? ki1i2…ik

其中 k 是查询( 1≤k≤n2+1 )中的索引数, i1,…,ik 是索引本身,满足 1≤i1<i2<…<ik≤n2+1 。**各项指标应按顺序排列

作为响应,交互器将以以下格式打印一行:

—— cj1j2…jc

其中 c 是查询( 1≤c≤k )中可见摩天大楼的数量, j1,…,jc 是它们的索引,满足 1≤j1<j2<…<jc≤n2+1 。索引将按排序顺序显示。

要报告你的最终答案,按以下格式打印一行:

            • ! s1s2…sn+1

其中 s1,…,sn+1 是组成长度为 n+1 的单调子序列的元素的索引,满足 1≤s1<s2<…<sn+1≤n2+1 。**各项指标应按顺序排列

注意,回答不会将计算在命令的限制中。

在打印答案之后,您的程序应该继续进行下一个测试用例,或者如果没有更多的测试用例就终止。

在打印每个查询之后,不要忘记输出行尾并刷新 ∗ 输出。否则,您将得到闲置限制超过判决。

如果在任何交互步骤中读取 −1 而不是有效数据,则必须立即退出解决方案。这意味着您的解决方案将收到错误的答案,因为无效的查询或任何其他错误。未能退出可能导致任意判定,因为您的解决方案将继续从已关闭的流中读取数据。


要破解,请使用以下格式。

第一行应该包含一个整数 t ( 1≤t≤5000 )。

每个测试用例的第一行应该包含一个整数 n ( 1≤n≤100 )。

每个测试用例的第二行应该包含 n2+1 个空格分隔的整数 p1,p2,…,pn2+1 ( 1≤pi≤n2+1 )。 p 应该是长度为 n2+1 的排列。

n2+1 的总和不应超过 10001 。

例如,test示例的hack格式如下:

∗ 要刷新,请使用:

  • c++中的fflush(stdout)或cout.flush();

  • Python中的sys.stdout.flush();

-查看其他语言的文档。

Example

Input

Copy

2
1

2 1 2

2

1 1

2 2 3

Output

Copy

? 2 1 2

! 1 2

? 3 1 2 3

? 3 2 3 5

! 1 3 4

Note

For the first test case, n=1. The hidden permutation is p=[1,2].

  • For the query ? 2 1 2, the visible skyscrapers are at indices 1 and 2. The interactor returns 2 1 2.
  • An increasing subsequence of length 2 at indices 1,2 is reported.

For the second test case, n=2. The hidden permutation is p=[5,3,4,1,2].

  • For the query ? 3 1 2 3, the visible skyscraper is at index 1. The interactor returns 1 1.
  • For the query ? 3 2 3 5, the visible skyscrapers are at indices 2 and 3. The interactor returns 2 2 3.
  • A decreasing subsequence of length 3 at indices 1,3,4 is reported.

Although Faker will play the role of interactor, the interactor will never lie to you.

有道 翻译

注意

对于第一个测试用例, n=1 。隐藏的排列是 p=[1,2] 。

-查询?2 1 2,可见的摩天大楼位于索引 1 和 2 。交互器返回2 1 2。

—报告索引为 1,2 的长度为 2 的子序列越来越大。

对于第二个测试用例, n=2 。隐藏的排列是 p=[5,3,4,1,2] 。

-查询?3 1 2 3,可见摩天大楼的索引为 1 。交互器返回11。

-查询?3 2 3 5,可见摩天大楼的索引为 2 和 3 。交互器返回2 2 3。

-报告索引为 1,3,4 的长度递减的子序列为 3 。

虽然Faker将扮演互动者的角色,但互动者永远不会对你撒谎。

思路

询问所有数,然后去除已得数,n次询问,若有一次询问可行,则输出,否则贪心。

代码见下

#include<bits/stdc++.h>
using namespace std;
int t,n,f[100005],s[105][10005],cs[10005],lks=0,vd=0,d7=0;
int main(){
    cin>>t;
    while(t--){
        cin>>n;
        lks=n*n+1;
        vd=0;
        for(int i=1;i<=n*n+1;i++){
            f[i]=0;
        }
        for(int i=1;i<=n;i++){
            cout<<"? "<<lks<<" ";
            //fflush(stdout);
            for(int j=1;j<=n*n+1;j++){
                if(f[j]==0){
                    cout<<j<<" ";
                    //fflush(stdout);
                }
            }
            cout<<endl;
            //fflush(stdout);
            cin>>s[i][0];
            lks-=s[i][0];
            for(int j=1;j<=s[i][0];j++){
                cin>>s[i][j];
                f[s[i][j]]=1;
            }
            if(s[i][0]>=n+1){
                cout<<"! ";
                //fflush(stdout);
                for(int j=1;j<=n+1;j++){
                    cout<<s[i][j]<<" ";
                    //fflush(stdout);
                }
                cout<<endl;
                //fflush(stdout);
                vd=1;
                break;
            }
        }
        if(vd==0){
            cs[0]=0;
            for(int i=n*n+1;i>=1;i--){
                if(f[i]==0){
                    d7=i;
                    break;
                }
            }
            cs[++cs[0]]=d7;
            for(int i=n;i>=1;i--){
                for(int j=s[i][0];j>=1;j--){
                    if(s[i][j]<=d7){
                        d7=s[i][j];
                        break;
                    }
                }
                cs[++cs[0]]=d7;
            }
            cout<<"! ";
            //fflush(stdout);
            for(int i=n+1;i>=1;i--){
                cout<<cs[i]<<" ";
                //fflush(stdout);
            }
            cout<<endl;
            //fflush(stdout);
        }
    }
	return 0;
}

posted @ 2025-10-16 10:10  bz02_2023f2  阅读(6)  评论(0)    收藏  举报  来源