CF-1451 E Bitwise Queries 异或 交互题
E - Bitwise Queries
题意
有一组序列,长度为 \(n(4\le n \le 2^{16})\),且 \(n\) 为 2 的整数次幂,序列中数值范围为 [0,n-1], 每次可以发起一次询问,询问分为以下几种:
- AND i j
- XOR i j
- OR i j
即序列中第 i 个数字和第 j 个数字的位运算结果,请你在不超过 n+1 次询问前提下求出这个序列。
此题的简单版本询问次数不超过 n+2 次。
首先要知道这几条规则:
- a + b = a ^ b + 2 * (a & b)
- a ^ c = (a ^ b) ^ (b ^ c)
所以可以如下操作:
int xorab = a ^ b, xorac = a ^ c, xorbc = xorab ^ xorac;
int andab = a & b, andbc = b & c, andac = a & c;
int ab = xorab + 2 * andab;
int bc = xorbc + 2 * andbc;
int ac = xorac + 2 * andac;
int a = (ab + ac - bc) / 2;
b = a ^ xorab;
c = a ^ xorac;
如上,可以在 5 次询问得到 a, b, c 的值,那么剩余的 n-3 个值,可以在 n-3 次询问得到
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, xorvals[N], res[N];
int query(string s, int x, int y){
cout << s << ' ' << x << ' ' << y << endl;
cout.flush();
int dest; cin >> dest;
if(dest == -1) exit(0);
return dest;
}
int main(){
cin >> n;
xorvals[1] = 0;
for(int i=2;i<=n;i++) {
xorvals[i] = query("XOR", 1, i);
}
int xorab = xorvals[2], xorac = xorvals[3], xorbc = xorab ^ xorac;
int andab = query("AND", 1, 2), andbc = query("AND", 2, 3), andac = query("AND", 1, 3);
int ab = xorab + 2 * andab;
int bc = xorbc + 2 * andbc;
int ac = xorac + 2 * andac;
res[1] = (ab + ac - bc) / 2;
for(int i=2;i<=n;i++) res[i] = xorvals[i] ^ res[1];
cout << "! ";
for(int i=1;i<=n;i++) cout << res[i] << ' ';
puts("");
return 0;
}
接下来讨论如何省掉一个询问。
不妨假设一种情况,这 n 个数字中有两个数字是一样的,假设是第 i 个和第 j 个,那么一定有 \(a_1 \land a_i = a_1 \land a_j\), 另外 \(a_i = a_i \& a_j\), 可以通过一组询问 "AND i j" 来得到这两个数值的值,这种情况总共需要 n 次询问。
另外一种情况,将是 [0, n-1] 中的每个数字都会出现恰好一次,这就使得对于每个数字 i,都可以找到一个 j,使得 \(a_i \land a_j = n-1\) ,并且不需要询问就可以知道这两个数字的逻辑且运算结果为 0,即 \(a_i \& a_j = 0\), 这个意味着什么呢?这可以为我们省掉一个 "AND" 询问,对标上面的 n-2 次询问的做法,这里仅需要 n-1 次询问。
#include <bits/stdc++.h>
using namespace std;
const int N = (1 << 16) + 5;
int n, xorvals[N], res[N];
vector<int> pos[N];
int query(string s, int i, int j){
cout << s << ' ' << i << ' ' << j << endl;
cout.flush();
int dest;
cin >> dest;
if(dest == -1) exit(0);
return dest;
}
int main(){
cin >> n;
xorvals[1] = 0;
pos[0].push_back(1);
for(int i=2;i<=n;i++){
xorvals[i] = query("XOR", 1, i);
pos[ xorvals[i] ].push_back(i);
}
// same 判断是否存在与 a[1] 异或值一样的数字
int same = -1, a = 1, b = -1, c = -1;
for(int i=0;i<n;i++){
if(pos[i].size() > 1){
same = 1;
b = pos[i][0];
c = pos[i][1];
}
}
if(same == -1) {// 若不存在一样的数字,表示[0,n-1] 中的每个数字都将出现
for(int i=2;i<=n;i++){
if(xorvals[i] == n-1){ // 找到与 res[1] 对应的数字,可以省掉一个 “AND” 询问
b = i;break;
}
}
// 随便找一个第三个数字
if(b == 2) c = 3;
else c = 2;
int xorab = xorvals[b], xorac = xorvals[c], xorbc = xorvals[b] ^ xorvals[c];
int andab = 0, andbc = query("AND", b, c), andac = query("AND", a, c);
int ab = xorab + 2 * andab;
int bc = xorbc + 2 * andbc;
int ac = xorac + 2 * andac;
res[1] = (ab + ac - bc) / 2;
} else { // 若存在,对标第一种情况
res[b] = query("AND", b, c);
res[1] = res[b] ^ xorvals[b];
}
for(int i=2;i<=n;i++) res[i] = res[1] ^ xorvals[i];
cout << "! ";
for(int i=1;i<=n;i++) cout << res[i] << ' ';
cout << endl;
return 0;
}
CF-1451 E Bitwise Queries 异或 交互题的更多相关文章
- B. Lost Number【CF交互题 暴力】
B. Lost Number[CF交互题 暴力] This is an interactive problem. Remember to flush your output while communi ...
- 【做题记录】CF1451E2 Bitwise Queries (Hard Version)
CF1451E2 Bitwise Queries (Hard Version) 题意: 有 \(n\) 个数( \(n\le 2^{16}\) ,且为 \(2\) 的整数次幂,且每一个数都属于区间 \ ...
- Codeforces Round #525 (Div. 2) D. Ehab and another another xor problem(交互题 异或)
题目 题意: 0≤a,b<2^30, 最多猜62次. 交互题,题目设定好a,b的值,要你去猜.要你通过输入 c d : 如果 a^c < b^d ,会反馈 -1 : 如果 a^c = b^ ...
- Codeforces Round #427 (Div. 2) E. The penguin's game (交互题,二进制分组)
E. The penguin's game time limit per test: 1 second memory limit per test: 256 megabytes input: stan ...
- CF1114E Arithmetic Progression(交互题,二分,随机算法)
既然是在CF上AC的第一道交互题,而且正是这场比赛让我升紫了,所以十分值得纪念. 题目链接:CF原网 题目大意:交互题. 有一个长度为 $n$ 的序列 $a$,保证它从小到大排序后是个等差数列.你不知 ...
- Codeforces Round #371 (Div. 2) D. Searching Rectangles 交互题 二分
D. Searching Rectangles 题目连接: http://codeforces.com/contest/714/problem/D Description Filya just lea ...
- E. XOR Guessing 交互题 Educational Codeforces Round 71 (Rated for Div. 2)
E. XOR Guessing 交互题. 因为这个数最多只有14位 0~13,所以我们可以先处理后面7位,然后再处理后面7位. 因为异或的性质,如果一个数和0异或,那么就等于本身. 所以我们第一次异或 ...
- 交互题[CF1103B Game with modulo、CF1019B The hat、CF896B Ithea Plays With Chtholly]
交互题就是程序与电脑代码的交互. 比如没有主函数的程序,而spj则给你一段主函,就变成了一个整体函数. 还有一种就是程序和spj之间有互动,这个用到fflush(stdout);这个函数就可以实现交互 ...
- Codeforces 1137D - Cooperative Game - [交互题+思维题]
题目链接:https://codeforces.com/contest/1137/problem/D 题意: 交互题. 给定如下一个有向图: 现在十个人各有一枚棋子(编号 $0 \sim 9$),在不 ...
随机推荐
- “==”和equals的区别
区别: (1)比较基本数据类型时 只能采用"==",比较的是数值; (2)当比较引用数据类型时 "==" 比较的是引用对象的内存地址; 而equals分两种情况 ...
- 切换用户后whoami打印用户的问题
问题: 为何第二个whoami打印的还是root? root@localhost /]# [root@localhost /]# [root@localhost /]# more test.sh #! ...
- 【MySQL】SELECT语句 - 查询数据
第4章 检索数据 文章目录 第4章 检索数据 1.SELECT语句 2.检索单个列 3.检索多个列 4.检索所有列 5.检索不同的行 6.限制结果 7.使用完全限定的表名 8.小结 简单记录 - My ...
- 【Oracle】10g 11g下载路径
现在直接点击不能下载了 要经过oracle许可才可以下载 如果嫌麻烦可以用迅雷直接下载密码是这个 一般不会动了 大家也不用帮我找回密码了 每次都改 也很麻烦的用迅雷下就不用密码了 下载也不会卡到最后 ...
- 电子邮箱、邮件地址、网站地址正则表达式!几个有用的RE、regex、regexp!
几个常用的正则表达式! r"\w[-\w\.]*@\w[-\w]*(\.\w[-\w]*)+" 这个是电子邮件地址的. r"<TAG\b[^>]*<(. ...
- Loadrunner录制脚本与编写脚本的区别
异同点: 1.录制的和编写的脚本质量上没有区别 2.性能脚本关心的是用户和服务器的数据交互,从这点上来看,录制和编写也没有区别,手动编写脚本也可以写出很真实的脚本 3.能录制的情况下,就录制吧,谁每天 ...
- DB2版本升级(V9.7升级到V11.1)
1.V11.1版本升级路线 DB2 11.1 可以将现有的 Db2 V9.7.Db2 V10.1 或 Db2 V10.5 实例和数据库直接升级到 Db2 V11.1.如果 Db2 服务器正在 Db2 ...
- 使用bapi创建PO遇到问题(BAPI_PO_CREATE1
今天用 BAPI_PO_CREATE1创建po. 注意事项: vendor 供应商号:长度必须和系统一致,10位.如 2000025要写成 0002000025传递给参数. POITEM 中的 PO_ ...
- 如何在K8s,Docker-Compose注入镜像Tag
最近在做基于容器的CI/CD, 一个朴素的自动部署的思路是: 从Git Repo打出git tag,作为镜像Tag ssh远程登录到部署机器 向部署环境注入镜像Tag,拉取镜像,重新部署 下面分享我是 ...
- 制作 Ubuntu 16.04 离线apt源
1.下载离线安装包 ubuntu下安装包都会下载到/var/cache/apt/archives下,首先清空该目录 sudo apt-get clean 下载需要安装包 sudo apt-get in ...