CodeForces - 1451E2 Bitwise Queries (Hard Version)(交互+构造+位运算)
题目链接:点击查看
题目大意:给出一个长度为 n(n 保证了是 2 的幂次),每个数的范围在 [ 0 , n - 1 ] 的一个数组,现在要求通过有限次操作确定下来这个数组:
- 询问 a[ i ] xor a[ j ] 的答案
- 询问 a[ i ] or a[ j ] 的答案
- 询问 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 ] 之内,我们分两种情况考虑:
- 假设至少存在两个数 a[ j ] 和 a[ k ] 相等,那么其与第三个数分别异或得到的结果显然也是相等的,符号语言就是:,如此一来我们就可以直接通过“与”运算或者“或”运算求出这两个数了,即,,然后对于剩下的 n - 2 个数进行异或运算反推,这种情况的询问复杂度是 1 + ( n - 2 ) = n - 1 次
- 假设所有的数两两都不相同,换句话 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)(交互+构造+位运算)相关推荐
- 【做题记录】CF1451E2 Bitwise Queries (Hard Version)
CF1451E2 Bitwise Queries (Hard Version) 题意: 有 \(n\) 个数( \(n\le 2^{16}\) ,且为 \(2\) 的整数次幂,且每一个数都属于区间 \ ...
- [CodeForces gym 102956 D] Bank Security Unification(位运算优化dp)
problem cf链接 solution 读完题先直接暴力 dpdpdp 拿出来,dpi=maxj<i{dpj+(fi&fj)}dp_i=\max_{j<i}\big\{dp_ ...
- Codeforces Gym 102956 C. Brave Seekers of Unicorns(位运算 + dp)
链接 :C. Brave Seekers of Unicorns 题意: 给你一个数 n (1 ≤ \leq ≤ n ≤ \leq ≤ 1e6),要求出有多少个严格单调递增的序列满足任意三个相邻的数满 ...
- 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) 根据上述式子 ...
- 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 ...
- CodeForces - 1234B2 Social Network (hard version)
CodeForces - 1234B2 Social Network (hard version) 题目: The only difference between easy and hard vers ...
- CodeForces - 1234B1 Social Network (easy version)
CodeForces - 1234B1 Social Network (easy version) 题目: The only difference between easy and hard vers ...
- Dreamoon Likes Sequences CodeForces - 1330D(组合数学+位运算)
Dreamoon likes sequences very much. So he created a problem about the sequence that you can't find i ...
- 在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) 我将省略有关我是如何做到这一点 ...
最新文章
- 零样本风格迁移:多模态CLIP文本驱动图像生成
- 干得累死,并不见得老板就待见你?——来自多位专家的见解
- 【Android 应用开发】 ActionBar 基础
- 【SDL】SDL学习笔记二 定时器
- Qt Designer中部件的tabletTracking和mouseTracking属性
- java jdk安装与环境变量配置
- 【CCF】 201604-1折点计数
- Intellij IDEA 自定义方法注释/方法模板
- systemtap notes
- 单链表的基本操作---插入,删除,交,并,相邻元素的交换等
- 【TCP/IP】【测试】常用抓包软件一览
- 【Unity】文字游戏制作插件Fungus教程(1)基础的使用方法
- android ndk下载安装教程,安装android NDK详细步骤
- js实现图片跟随鼠标移动
- 电脑重装系统之后MySQl如何恢复
- 备案的是域名还是服务器?
- MYS-6ULX-IOT 开发板测评——实现简单的物联网应用
- sencha app watch php,Sencha Touch构建移动端App
- 怎样做一个更有价值的人
- 算式最大值 (思维题)
热门文章
- flink启动命令参数_[Flink]Flink1.3 指南四 命令行接口-阿里云开发者社区
- mysql size_mysql fetch size 相关问题
- MySQL查看索引使用情况
- 初识Caffeine
- SpringSecurity权限控制之异常处理方式二
- MyBatis 的工作流程分析
- 如何向Spring Bean 中注入java.util.Properties?
- Hive的基本操作-创建分区表
- Hystrix Dashboard的使用与常见问题总结
- Oracle 同义词、DBLINK、表空间的使用