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. 【SQL】所谓的连表查询

    连表查询 外连接 外连接分为两种,左(外)连接和右(外)连接 基本语法如下: SELECT 字段列表 FROM 表1 LEFT JOIN 表2 ON 条件; 这是左连接,因此以表1中的 [字段列表] ...

  2. 为什么要使用API接口,他能带来哪些便利

    API接口是程序员进行应用程序开发时不可或缺的工具之一.以下是使用API接口的一些优点: 数据交换:使用API接口可以使不同的应用程序.网站或服务之间交换数据更为便捷,减少人工输入数据的时间和风险. ...

  3. xv6 进程切换中的锁:MIT6.s081/6.828 lectrue12:Coordination 以及 Lab6 Thread 心得

    引言 这节课和上一节xv6进程切换是一个完整的的进程切换专题,上一节主要讨论进程切换过程中的细节,而这一节主要讨论进程切换过程中锁的使用,所以本节的两大关键词就是"Coordination& ...

  4. 拉普拉斯金字塔在多图HDR算法中的应用以及多曝光图像的融合算法简介。

    在SSE图像算法优化系列二十九:基础的拉普拉斯金字塔融合用于改善图像增强中易出现的过增强问题(一) 一文中我们曾经描述过基于几种高频融合法则的拉普拉斯金字塔融合算法,那里是主要针对2副图像的.实际的应 ...

  5. Record -「Tricks」记录

    曼哈顿距离 \(\text{dist}(A,B)=|x_{A}-x_{B}|+|y_{A}-y_{B}|\) 可以拆成 \(\max\{x_{A}-x_{B}+y_{A}-y_{B},x_{A}-x_ ...

  6. 低代码引擎 TinyEngine 正式发布!

    在当今数字化飞速发展的时代,企业对高效.敏捷的应用程序需求日益旺盛.为了满足这一需求,越来越多的低代码开发平台开始涌现.这些平台通过提供简单易用的开发工具和优化后的开发流程,帮助开发者快速构建高质量. ...

  7. Go语言系列——21-Go协程、22-信道(channel)、23-缓冲信道和工作池、24-Select、25-Mutex、26-结构体取代类、27-组合取代继承、多态、 29-Defer、错误处理

    文章目录 21-Go协程 Go 协程是什么? Go 协程相比于线程的优势 如何启动一个 Go 协程? 启动多个 Go 协程 22-信道(channel) 什么是信道? 信道的声明 通过信道进行发送和接 ...

  8. Asp-Net-Core开发笔记:EFCore统一实体和属性命名风格

    前言 C# 编码规范中,类和属性都是大写驼峰命名风格(PascalCase / UpperCamelCase),而在数据库中我们往往使用小写蛇形命名(snake_case),在默认情况下,EFCore ...

  9. oracle命令3 冷备份

    用户管理的备份:备份脚本要自己写:备份哪些文件要自己选:恢复时要复制那些文件自己判断:恢复需要的日志,自己找: 备份,需要备份保存关键SCN信息的文件:一次完成的备份包括:控制文件,数据文件,日志文件 ...

  10. CF1338A

    题目简化和分析: \(a_{i}\ge a_{i-1}\) 已经满足直接跳过 \(a_{i}<a_{i-1}\) 我们就要将其的差进行二进制的分解,使得 \(a_{i-1}=a_i\) 我也不知 ...