X-OR

题面翻译

题目描述

本题是交互题

有一个固定的长度为 \(n\) 的排列 \(P\),其值域为 \([0,n-1]\),你可以进行不超过 \(4269\) 次询问,之后你需要输出这个排列 \(P\)。

输入格式

第一行有一个正整数 \(n\),表示排列的长度。

保证 \(3\le n\le 2048\),\(0\le P_i\le n-1\)。

交互格式

你可以按照 ? a b 的格式进行询问,之后你会得到 \(P_a\) 与 \(P_b\) 的按位或。

当你需要输出 \(P\) 时,首先输出一个 !,之后输出 \(n\) 个整数 \(P_i\)。

题目描述

This is an interactive problem!

Ehab has a hidden permutation $ p $ of length $ n $ consisting of the elements from $ 0 $ to $ n-1 $ . You, for some reason, want to figure out the permutation. To do that, you can give Ehab $ 2 $ different indices $ i $ and $ j $ , and he'll reply with $ (p_i|p_j) $ where $ | $ is the bitwise-or operation.

Ehab has just enough free time to answer $ 4269 $ questions, and while he's OK with answering that many questions, he's too lazy to play your silly games, so he'll fix the permutation beforehand and will not change it depending on your queries. Can you guess the permutation?

输入格式

The only line contains the integer $ n $ $ (3 \le n \le 2048) $ — the length of the permutation.

输出格式

To ask a question, print "? $ i $ $ j $ " (without quotes, $ i \neq j $ ) Then, you should read the answer, which will be $ (p_i|p_j) $ .

If we answer with $ -1 $ instead of a valid answer, that means you exceeded the number of queries or made an invalid query.

Exit immediately after receiving $ -1 $ and you will see wrong answer verdict. Otherwise, you can get an arbitrary verdict because your solution will continue to read from a closed stream.

To print the answer, print "! $ p_1 $ $ p_2 $ $ \ldots $ $ p_n $ " (without quotes). Note that answering doesn't count as one of the $ 4269 $ queries.

After printing a query or printing the answer, do not forget to output 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 the documentation for other languages.

Hacks:

The first line should contain the integer $ n $ ( $ 3 \le n \le 2^{11} $ ) — the length of the permutation $ p $ .

The second line should contain $ n $ space-separated integers $ p_1 $ , $ p_2 $ , $ \ldots $ , $ p_n $ ( $ 0 \le p_i < n $ ) — the elements of the permutation $ p $ .

样例 #1

样例输入 #1

3
1
3
2

样例输出 #1

? 1 2
? 1 3
? 2 3
! 1 0 2

提示

In the first sample, the permutation is $ [1,0,2] $ . You start by asking about $ p_1|p_2 $ and Ehab replies with $ 1 $ . You then ask about $ p_1|p_3 $ and Ehab replies with $ 3 $ . Finally, you ask about $ p_2|p_3 $ and Ehab replies with $ 2 $ . You then guess the permutation.

只要找到 \(0\) 所在的位置,我们就可以轻松求出其他地方的值了。

关键在于如何快速找到 \(0\) 所在的位置。

先考虑如何快速求出某一位 \(i\) 的值。暴力的话枚举所有其他位置,询问 \(i,j\),然后所有得到的结果取个与就行了。

发现不用枚举所有位置,期望情况下,取 一次与,二进制下 1 的个数会除以2,只要随机 \(log logn\) 个位置询问取与就足够了。具体可以随机十个数。

求出某个数 \(p_i\),后,如果询问 \(p_i 或 p_j\ne p_i\),那么 \(j\) 不可能是 \(0\),否则求出 \(p_j\) 的答案。

发现询问时 \(p_i\) 二进制下 1 的个数会不断减少,所以只会询问 \(log\) 次可以得到 \(0\) 的位置,然后就好做了。总共询问次数 \(2n+lognlog logn\)

#include<bits/stdc++.h>
using namespace std;
const int N=3005;
mt19937 gen(time(0));
int n,p[N],lst,cnt,pt[N];
int ask(int x,int y)
{
printf("? %d %d\n",x,y);
fflush(stdout);
int a;
scanf("%d",&a);
return a;
// ++cnt;
// return pt[x]|pt[y];
}
void answer(int x)
{
// printf("%d\n",x);
for(int i=1;i<=n;i++)
if(x^i)
p[i]=ask(x,i);
p[x]=0;
putchar('!'),putchar(' ');
for(int i=1;i<=n;i++)
printf("%d ",p[i]);
fflush(stdout);
// for(int i=1;i<=n;i++)
// if(p[i]^pt[i])
// return puts("failed"),void();
// printf("succes %d",cnt);
}
int calc(int x)
{
int mn=32767;
for(int T=1;T<=10;T++)
{
int k=gen()%n+1;
if(k^x)
mn&=ask(x,k);
}
return mn;
}
int main()
{
scanf("%d",&n);
lst=1,p[1]=calc(1);
for(int i=2;i<=n;i++)
{
if(ask(i,lst)==p[lst])
{
p[i]=calc(i);
lst=i;
}
}
answer(lst);
}

随机推荐

  1. AI绘画StableDiffusion:云端在线版免费使用笔记分享-Kaggle版

    玩AI绘画(SD),自己电脑配置不够?今天给大家介绍一下如何baipiao在线版AI绘画StableDiffusion. Kaggle 是世界上最大的数据科学社区,拥有强大的工具和资源,可帮助您实现数 ...

  2. 在.NET Framework中使用RocketMQ(阿里云版)实战【第二章】

    章节 第一章:https://www.cnblogs.com/kimiliucn/p/17662052.html 第二章:https://www.cnblogs.com/kimiliucn/p/176 ...

  3. Dynamics 365 自定义渠道的步骤

    1.创建2个实体:渠道[new_flashinfosmschannel].消息模板(配置窗体)注意:如果想用标准消息模板,可以不用创建消息模板 标准消息模板效果: 2.导出解决方案,往XML增加一个关 ...

  4. 避坑|在读取excel.xlsx文件中的内容时发现明明只有3行,但跑起来却认为有13行,导致有10行None,UI自动化测试代码空跑了10次;|UI自动化测试|数据驱动

    在读取excel.xlsx文件中的内容时发现明明只有3行,但跑起来却认为有13行,导致有10行None,UI自动化测试代码空跑了10次: 原因:excel.xlsx内容清除时用delete快捷键导致, ...

  5. Solution -「九省联考 2018」劈配

    Description Link. 一年一度的综艺节目<中国新代码>又开始了.Zayid 从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. 轻车熟路的 Za ...

  6. Solution -「九省联考 2018」IIIDX

    Description Link. 给出一个堆,然后让你填数进去,使得其满足小根堆的性质,并使编号靠前的点的数最大. Solution 考虑贪心,把原数列降序排序,然后因为这个东西是整除分块的形式,所 ...

  7. Solution -「LOCAL 28731」「重庆市 2021 中学友谊赛」Rainyrabbit 爱求和

    Description Link. \(\operatorname{Rainyrabbit}\) 是一个数学极好的萌妹子,近期他发现了一个可爱的函数: \[f(n,m,k)=\sum_{d=1}^n ...

  8. Blazor Server 发起HttpPost请求,但是多参数

    一.介绍 今天突然想起之前工作上遇到的一个问题,在做Blazor 开发时后端给的一个接口请求方式是Post ,但是他需要携带多个参数,新建一个公共类又觉得麻烦,我就尝试着怎么在Post请求中携带多个参 ...

  9. C++ STL 容器简单讲解

    STL 简单讲解 网上有很多很好的资料可以参考 而直接看标准是最准确清晰的 vector stack queue / priority_queue deque array map / multimap ...

  10. Linux系列教程——Shell、Linux文件管理

    文章目录 Shell 1.什么是Bash shell(壳) 2.Bash Shell能干什么? 3.平时我们如何使用Shell呢? 4.Shell提示符 5.Shell基础语法 2.Bash Shel ...