题目链接:点击查看

题目大意:给出一个长度为 n(n 保证了是 2 的幂次),每个数的范围在 [ 0 , n - 1 ] 的一个数组,现在要求通过有限次操作确定下来这个数组:

  1. 询问 a[ i ] xor a[ j ] 的答案
  2. 询问 a[ i ] or a[ j ] 的答案
  3. 询问 a[ i ] and a[ j ] 的答案

题目分析:因为可以询问任意两个数异或运算后的答案,根据 ,我们可以先确定出序列中的任意一个数字设为 x,然后对于其他的数字依次询问与 x 的异或,就可以反推出所有的数字了,所以现在问题转换成如何在有限次操作中确定下来某个数字的取值

E1 是最多询问 n + 2 次,E2 是最多询问 n + 1 次,先简单说一下 E1 的做法,对于位运算和加法运算之间有个公式是:

对于每组样例,我们可以任取三个数字 a[ i ] , a[ j ] , a[ k ],利用上述公式通过六次询问求出 a[ i ] + a[ j ],a[ i ] + a[ k ],a[ j ] + a[ k ],现在是三个未知数+三个等式就可以分别求出 a[ i ] , a[ j ] , a[ k ] 的值了,对于剩下的 n - 3 个数来说,依次与 a[ i ] 或 a[ j ] 或 a[ k ] 进行异或操作就可以反推出答案了,不过很可惜的是,这样的做法询问次数是 6 + ( n - 3 ) = n + 3 次

还是由于异或运算的性质,当我们知道  和后,将这两个数进行异或运算就可以直接得到了,少去一次异或运算的询问复杂度就是 n + 2 次,已经可以通过 E1 了

到此为止,我们会发现,题目中给定的一个条件我们还没有用上,就是每个数的范围都在 [ 0 , n - 1 ] 之内,我们分两种情况考虑:

  1. 假设至少存在两个数 a[ j ] 和 a[ k ] 相等,那么其与第三个数分别异或得到的结果显然也是相等的,符号语言就是:,如此一来我们就可以直接通过“与”运算或者“或”运算求出这两个数了,即,然后对于剩下的 n - 2 个数进行异或运算反推,这种情况的询问复杂度是 1 + ( n - 2 ) = n - 1 次
  2. 假设所有的数两两都不相同,换句话 n 个数覆盖了 [ 0 , n - 1 ] 这一整个区间,又因为 n - 1 是 2 的幂次减一,换句话说 n - 1 在二进制下全部是 1 ,所以对于任意一个 x 来说,一定存在这一个 y,满足,也就是说 ,到此为止,根据  这个公式再随便选一个数字解方程即可,因为根据上述方法得到的 x 和 y 已经满足了这个条件,所以就可以少询问一次,所以在 E1 的基础上少了一次询问,询问复杂度就降低至了 n + 1 次

代码:

//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e6+100;int _xor[N],last[N],a[N];int interact(int i,int j,const char s[])
{printf("%s %d %d\n",s,i,j);fflush(stdout);int num;scanf("%d",&num);return num;
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);memset(last,-1,sizeof(last));last[0]=1;int n,id1=-1,id2=-1;scanf("%d",&n);for(int i=2;i<=n;i++){_xor[i]=interact(1,i,"XOR");//_xor[i]=a[1]^a[i]if(last[_xor[i]]!=-1)//a[1]^a[last[_xor[i]]]==a[1]^a[i]id1=last[_xor[i]],id2=i;//a[id1]=a[id2]last[_xor[i]]=i;}if(id1!=-1)//存在两个相同的数字 {a[id1]=a[id2]=interact(id1,id2,"AND");a[1]=a[id1]^_xor[id1];for(int i=2;i<=n;i++)a[i]=_xor[i]^a[1];}else//所有数字都不相同 {int id1=last[n-1];//a[1]^a[id1]=n-1 -> a[1]&a[id1]=0int id2=id1!=2?2:3;//随便再选一个数 int sum1=n-1;//a[1]+a[id1]int sum2=_xor[id2]+2*interact(1,id2,"AND");//a[1]+a[id2]int sum3=(_xor[id1]^_xor[id2])+2*interact(id1,id2,"AND");//a[id1]+a[id2]a[1]=(sum1+sum2-sum3)/2;for(int i=2;i<=n;i++)a[i]=_xor[i]^a[1];}printf("!");for(int i=1;i<=n;i++)printf(" %d",a[i]);return 0;
}

CodeForces - 1451E2 Bitwise Queries (Hard Version)(交互+构造+位运算)相关推荐

  1. 【做题记录】CF1451E2 Bitwise Queries (Hard Version)

    CF1451E2 Bitwise Queries (Hard Version) 题意: 有 \(n\) 个数( \(n\le 2^{16}\) ,且为 \(2\) 的整数次幂,且每一个数都属于区间 \ ...

  2. [CodeForces gym 102956 D] Bank Security Unification(位运算优化dp)

    problem cf链接 solution 读完题先直接暴力 dpdpdp 拿出来,dpi=max⁡j<i{dpj+(fi&fj)}dp_i=\max_{j<i}\big\{dp_ ...

  3. Codeforces Gym 102956 C. Brave Seekers of Unicorns(位运算 + dp)

    链接 :C. Brave Seekers of Unicorns 题意: 给你一个数 n (1 ≤ \leq ≤ n ≤ \leq ≤ 1e6),要求出有多少个严格单调递增的序列满足任意三个相邻的数满 ...

  4. codeforces1451 E. Bitwise Queries(位运算妙用)

    E1. Bitwise Queries (Easy Version) a+b=(a&b)+(a∣b)a+b=(a\&b)+(a|b)a+b=(a&b)+(a∣b) 根据上述式子 ...

  5. CodeForces 1616H Keep XOR Low {a^b≤x} / CodeForces gym102331 Bitwise Xor {a^b≥x}(trie树 + 计数)

    文章目录 CodeForces 1616H Keep XOR Low problem solution code CodeForces gym102331 Bitwise Xor problem so ...

  6. CodeForces - 1234B2 Social Network (hard version)

    CodeForces - 1234B2 Social Network (hard version) 题目: The only difference between easy and hard vers ...

  7. CodeForces - 1234B1 Social Network (easy version)

    CodeForces - 1234B1 Social Network (easy version) 题目: The only difference between easy and hard vers ...

  8. Dreamoon Likes Sequences CodeForces - 1330D(组合数学+位运算)

    Dreamoon likes sequences very much. So he created a problem about the sequence that you can't find i ...

  9. 在php中将5按位与运算,PHP 5.2和PHP 5.3中对大整数的按位运算(Bitwise operations on big integers in PHP 5.2 and PHP 5.3)...

    PHP 5.2和PHP 5.3中对大整数的按位运算(Bitwise operations on big integers in PHP 5.2 and PHP 5.3) 我将省略有关我是如何做到这一点 ...

最新文章

  1. 零样本风格迁移:多模态CLIP文本驱动图像生成
  2. 干得累死,并不见得老板就待见你?——来自多位专家的见解
  3. 【Android 应用开发】 ActionBar 基础
  4. 【SDL】SDL学习笔记二 定时器
  5. Qt Designer中部件的tabletTracking和mouseTracking属性
  6. java jdk安装与环境变量配置
  7. 【CCF】 201604-1折点计数
  8. Intellij IDEA 自定义方法注释/方法模板
  9. systemtap notes
  10. 单链表的基本操作---插入,删除,交,并,相邻元素的交换等
  11. 【TCP/IP】【测试】常用抓包软件一览
  12. 【Unity】文字游戏制作插件Fungus教程(1)基础的使用方法
  13. android ndk下载安装教程,安装android NDK详细步骤
  14. js实现图片跟随鼠标移动
  15. 电脑重装系统之后MySQl如何恢复
  16. 备案的是域名还是服务器?
  17. MYS-6ULX-IOT 开发板测评——实现简单的物联网应用
  18. sencha app watch php,Sencha Touch构建移动端App
  19. 怎样做一个更有价值的人
  20. 算式最大值 (思维题)

热门文章

  1. flink启动命令参数_[Flink]Flink1.3 指南四 命令行接口-阿里云开发者社区
  2. mysql size_mysql fetch size 相关问题
  3. MySQL查看索引使用情况
  4. 初识Caffeine
  5. SpringSecurity权限控制之异常处理方式二
  6. MyBatis 的工作流程分析
  7. 如何向Spring Bean 中注入java.util.Properties?
  8. Hive的基本操作-创建分区表
  9. Hystrix Dashboard的使用与常见问题总结
  10. Oracle 同义词、DBLINK、表空间的使用