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. 当 GPT-4 拥有了 Diff 视图,那真的是如虎添翼!

    目录 1. 当你要求 GPT-4 帮你写点代码时 2. 你需要的背景知识都在这里 2.1 关于 GoPool 和 DevChat 2.2 关于 GoPool 的工作原理 2.3 我想要让 taskQu ...

  2. 单节点 RAID6 可靠性模型

    介绍 独立磁盘冗余阵列(Redundant Arrays of Independent Disks, RAID)是存储业界为保证数据可用性.可靠性和完整性所采用的重要技术,即使在分布式多副本如此流行和 ...

  3. uwsgi配置

    编辑nginx配置: server { listen 8098; server_name 127.0.0.1; location / { include uwsgi_params; # uwsgi_p ...

  4. 每日一题:如何判断是否是数组,一个既简单又复杂的问题。(不要再用Object.prototype.toString.call、instance of判断了!!!)

    1.不要使用Object.prototype.toString.call() 正常情况下: const arr = [1,2,3,4,5] const obj = {} console.log(Obj ...

  5. Solution -「洛谷 P4689」「YunoOI 2016」这是我自己的发明

    Description Link. 给一个树,\(n\) 个点,有点权,初始根是 1. \(m\) 个操作,种类如下: 1 x 将树根换为 \(x\). 2 x y 给出两个点 \(x,y\),从 \ ...

  6. 用策略模式干掉代码里大量的if-eles或则Swatch,提升B格由面向过程转为面向对象

    现象 大量的分支选择型代码段看着让人头疼 for (Field field : declaredFields) { Class<?> type = field.getType(); Str ...

  7. open与fopen的区别

    1. 来源 从来源的角度看,两者能很好的区分开,这也是两者最显而易见的区别: open是UNIX系统调用函数(包括LINUX等),返回的是文件描述符(File Descriptor),它是文件在文件描 ...

  8. LUSH & LUXURIOUS

    明亮色系Punchy & Bright 明亮.有着强烈对比的颜色更引人注目. 这种大胆的色彩组合要谨慎地利用,所以在明亮色系中的调和色一般用中性色. 其中不同的色彩饱和度,表现出不同的氛围和意 ...

  9. 使用Java统计gitlab代码行数

    一.背景: 需要对当前公司所有的项目进行代码行数的统计 二. 可实现方式 1.脚本:通过git脚本将所有的项目拉下来并然后通过进行代码行数的统计 样例: echo 创建项目对应的文件夹 mkdir 项 ...

  10. 多源异构数据信息的融合方式0 - Dempster/Shafer 证据理论(D-S证据理论)

    Dempster/Shafer 证据理论(D-S证据理论)的大体内容如下: 一.简介: 在理论中,由互不相容的基本命题组成的完备集合Θ称为识别框架,表示对于某一问题的所有可能答案,但是只有一个答案是正 ...