E - Bitwise Queries

传送门

题意

有一组序列,长度为 \(n(4\le n \le 2^{16})\),且 \(n\) 为 2 的整数次幂,序列中数值范围为 [0,n-1], 每次可以发起一次询问,询问分为以下几种:

  1. AND i j
  2. XOR i j
  3. OR i j

即序列中第 i 个数字和第 j 个数字的位运算结果,请你在不超过 n+1 次询问前提下求出这个序列。

此题的简单版本询问次数不超过 n+2 次。

首先要知道这几条规则:

  1. a + b = a ^ b + 2 * (a & b)
  2. a ^ c = (a ^ b) ^ (b ^ c)

所以可以如下操作:

  1. int xorab = a ^ b, xorac = a ^ c, xorbc = xorab ^ xorac;
  2. int andab = a & b, andbc = b & c, andac = a & c;
  3. int ab = xorab + 2 * andab;
  4. int bc = xorbc + 2 * andbc;
  5. int ac = xorac + 2 * andac;
  6. int a = (ab + ac - bc) / 2;
  7. b = a ^ xorab;
  8. c = a ^ xorac;

如上,可以在 5 次询问得到 a, b, c 的值,那么剩余的 n-3 个值,可以在 n-3 次询问得到

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N = 100010;
  4. int n, xorvals[N], res[N];
  5. int query(string s, int x, int y){
  6. cout << s << ' ' << x << ' ' << y << endl;
  7. cout.flush();
  8. int dest; cin >> dest;
  9. if(dest == -1) exit(0);
  10. return dest;
  11. }
  12. int main(){
  13. cin >> n;
  14. xorvals[1] = 0;
  15. for(int i=2;i<=n;i++) {
  16. xorvals[i] = query("XOR", 1, i);
  17. }
  18. int xorab = xorvals[2], xorac = xorvals[3], xorbc = xorab ^ xorac;
  19. int andab = query("AND", 1, 2), andbc = query("AND", 2, 3), andac = query("AND", 1, 3);
  20. int ab = xorab + 2 * andab;
  21. int bc = xorbc + 2 * andbc;
  22. int ac = xorac + 2 * andac;
  23. res[1] = (ab + ac - bc) / 2;
  24. for(int i=2;i<=n;i++) res[i] = xorvals[i] ^ res[1];
  25. cout << "! ";
  26. for(int i=1;i<=n;i++) cout << res[i] << ' ';
  27. puts("");
  28. return 0;
  29. }

接下来讨论如何省掉一个询问。

不妨假设一种情况,这 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 次询问。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N = (1 << 16) + 5;
  4. int n, xorvals[N], res[N];
  5. vector<int> pos[N];
  6. int query(string s, int i, int j){
  7. cout << s << ' ' << i << ' ' << j << endl;
  8. cout.flush();
  9. int dest;
  10. cin >> dest;
  11. if(dest == -1) exit(0);
  12. return dest;
  13. }
  14. int main(){
  15. cin >> n;
  16. xorvals[1] = 0;
  17. pos[0].push_back(1);
  18. for(int i=2;i<=n;i++){
  19. xorvals[i] = query("XOR", 1, i);
  20. pos[ xorvals[i] ].push_back(i);
  21. }
  22. // same 判断是否存在与 a[1] 异或值一样的数字
  23. int same = -1, a = 1, b = -1, c = -1;
  24. for(int i=0;i<n;i++){
  25. if(pos[i].size() > 1){
  26. same = 1;
  27. b = pos[i][0];
  28. c = pos[i][1];
  29. }
  30. }
  31. if(same == -1) {// 若不存在一样的数字,表示[0,n-1] 中的每个数字都将出现
  32. for(int i=2;i<=n;i++){
  33. if(xorvals[i] == n-1){ // 找到与 res[1] 对应的数字,可以省掉一个 “AND” 询问
  34. b = i;break;
  35. }
  36. }
  37. // 随便找一个第三个数字
  38. if(b == 2) c = 3;
  39. else c = 2;
  40. int xorab = xorvals[b], xorac = xorvals[c], xorbc = xorvals[b] ^ xorvals[c];
  41. int andab = 0, andbc = query("AND", b, c), andac = query("AND", a, c);
  42. int ab = xorab + 2 * andab;
  43. int bc = xorbc + 2 * andbc;
  44. int ac = xorac + 2 * andac;
  45. res[1] = (ab + ac - bc) / 2;
  46. } else { // 若存在,对标第一种情况
  47. res[b] = query("AND", b, c);
  48. res[1] = res[b] ^ xorvals[b];
  49. }
  50. for(int i=2;i<=n;i++) res[i] = res[1] ^ xorvals[i];
  51. cout << "! ";
  52. for(int i=1;i<=n;i++) cout << res[i] << ' ';
  53. cout << endl;
  54. return 0;
  55. }

CF-1451 E Bitwise Queries 异或 交互题的更多相关文章

  1. B. Lost Number【CF交互题 暴力】

    B. Lost Number[CF交互题 暴力] This is an interactive problem. Remember to flush your output while communi ...

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

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

  3. 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^ ...

  4. 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 ...

  5. CF1114E Arithmetic Progression(交互题,二分,随机算法)

    既然是在CF上AC的第一道交互题,而且正是这场比赛让我升紫了,所以十分值得纪念. 题目链接:CF原网 题目大意:交互题. 有一个长度为 $n$ 的序列 $a$,保证它从小到大排序后是个等差数列.你不知 ...

  6. Codeforces Round #371 (Div. 2) D. Searching Rectangles 交互题 二分

    D. Searching Rectangles 题目连接: http://codeforces.com/contest/714/problem/D Description Filya just lea ...

  7. E. XOR Guessing 交互题 Educational Codeforces Round 71 (Rated for Div. 2)

    E. XOR Guessing 交互题. 因为这个数最多只有14位 0~13,所以我们可以先处理后面7位,然后再处理后面7位. 因为异或的性质,如果一个数和0异或,那么就等于本身. 所以我们第一次异或 ...

  8. 交互题[CF1103B Game with modulo、CF1019B The hat、CF896B Ithea Plays With Chtholly]

    交互题就是程序与电脑代码的交互. 比如没有主函数的程序,而spj则给你一段主函,就变成了一个整体函数. 还有一种就是程序和spj之间有互动,这个用到fflush(stdout);这个函数就可以实现交互 ...

  9. Codeforces 1137D - Cooperative Game - [交互题+思维题]

    题目链接:https://codeforces.com/contest/1137/problem/D 题意: 交互题. 给定如下一个有向图: 现在十个人各有一枚棋子(编号 $0 \sim 9$),在不 ...

随机推荐

  1. MySQL -- insert ignore语句

    项目实战 用户登记激活码记录插入接口 数据库测试实例,其中手机号和父设备id为唯一索引 当我们使用普通的insert语句插入一条数据库中已存在的手机号和父设备id的数据时,会报重复的key的错 当我们 ...

  2. 在Docker下进行MyCAT管理双主双从MySQL集群

    前言 在Docker下双主双从MySQL集群模拟 https://www.cnblogs.com/yumq/p/14259964.html 本文实验配置文件 Docker拉取MyCAT镜像 如果没启动 ...

  3. 【函数分享】每日PHP函数分享(2021-1-7)

    ltrim() 删除字符串开头的空白字符(或其他字符). string ltrim ( string $str[, string $character_mask]) 参数描述str 输入的字符串. c ...

  4. epoll的陷阱

    Starvation 特别提出在ET模式下,因为需要一次性把数据读完,如果一次性通知的数据过大,有可能处理时间过长,导致同一线程其他的事件长时间等待.这个不仅仅是ET模式下,也不仅仅是epoll模型下 ...

  5. .net core 和 WPF 开发升讯威在线客服与营销系统:使用 WebSocket 实现访客端通信

    本系列文章详细介绍使用 .net core 和 WPF 开发 升讯威在线客服与营销系统 的过程.本产品已经成熟稳定并投入商用. 在线演示环境:https://kf.shengxunwei.com 注意 ...

  6. 关联实现上-jsonpath取值

    举例子: demo01.py import jsonimport requestsimport jsonpathsession = requests.session()get_param_dict={ ...

  7. spring cloud gateway 日志打印

    从api请求中获取访问的具体信息,是一个很常见的功能,这几天在研究springcloud,使用到了其中的gateway,刚好将研究的过程结果都记录下来 0. Version <parent> ...

  8. ubuntu 安装 docker 并配置镜像加速(使用 apt-get 进行安装)

    ubuntu 安装docker CentOS docker安装 https://blog.csdn.net/weixin_44953227/article/details/108597310 你需要这 ...

  9. 微信登录4-开发回调URL

    一.准备 1.引入pom依赖 在要使用HttpClient的项目中加入依赖 <!--httpclient--> <dependency> <groupId>org. ...

  10. HTTP Keep-Alive模式客户端与服务器如何判定传输完成

    目录 长连接是什么 服务器如何知道已经完全接受客户端发送的数据 客户端如何知道已经完全接受服务端发送的数据 Transfer-Encoding transfer-coding与Content-Leng ...