当前位置: 首页 > news >正文

#724 D【位运算】

题目描述

给你n个数

然后对于每一个数 \(a_i\) ,判断是否存在一个 \(a_j\) ,使得 \(a_i \& a_j = 0\)

输入格式

第一行一个数 \(n\)

然后 \(n\) 个整数,表示 \(a_i\)

输出格式

一行,n个整数,表示答案

如果存在,输出1

否则,输出0

样例

【样例输入】

6 1 2 3 5 7 9

【样例输出】

1 1 0 1 0 1

基本思想

一开始我的想法是使用 \(trie\) 树储存所有 01串,然后使用 \(DFS\) 逐个查找。貌似使用了 \(trie\) 树会是查询更高效,实则我们想避开所有 1 ,会使 \(DFS\) 查询变成事实上的穷举\(trie\) 树的插入步骤的时间复杂度是 \(O(nL)\) ,但是查询操作仅仅对于每个数而言会有 \(O(2^L)\) ,这与暴力配对没有实质区别。

那么我们考虑是否可以将每个 01串可以符合的预期串预处理出来,也就是处理出它的补集,意即 0010--> 1101,1101 & 0010=0,但是我们在 1101 中删去几个 1 仍然是符合条件的,这就是我们预处理的方向。乍一看这个复杂度还是挺高的,但问题是题目要求我们判断存在,我们预处理出来之后查询是 \(O(1)\) 的,更何况我们从 \(2^{20}\) 向下遍历,我们在补集中删去 1 只会使数变小,得到的新数会向后加入进行再次处理,意思就是说我们不需要考虑枚举要删去多少个 1 ,而只需要考虑删去那个 1 即可。

Code

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
const int M=1<<20;
int n,m,a[N];
bool ok[M+10];
int main(){ios::sync_with_stdio(false);cin>>n;m=M-1;for(int i=1;i<=n;i++){cin>>a[i];ok[a[i]^m]=true;}for(int i=m;i>=0;i--)if(ok[i]){for(int j=0;j<=20;j++)if(i&(1<<j))ok[i^(1<<j)]=true;//去除1只会变小,会加到后面进行再次处理 }for(int i=1;i<=n;i++){cout<<ok[a[i]]<<" ";}return 0;
}
http://www.sczhlp.com/news/5822/

相关文章:

  • 48MW风电场Simulink仿真设计与实现
  • 基于内存认证的 Spring Security
  • Linux查看文件夹大小
  • InnoDB聚集索引与MyISAM非聚集索引
  • 修改kill_all,kill_all_by_cmdline,group_feed
  • vscode 左侧栏 显示隐藏 ctrl+b 查看:切换主侧栏可见性 View: Toggle Primary Side Bar Visibility
  • 【2025-08-03】连岳摘抄
  • 从零开发一个英语语音测评系统,序章
  • Java Date与LocalDateTime互相转换
  • ABAP不需要开发请求的代码修改--用于简单逻辑或者字段的修改
  • Hive配置
  • Linux chroot 命令详解与应用场景
  • PostgreSQL 安装
  • P5687 [CSP-S2019 江西] 网格图
  • Linux系统设置redis集群开机自启动
  • Luogu P2416 泡芙 题解 [ 蓝 ] [ 边双连通分量 ] [ LCA ]
  • codeql的一个测试
  • .NET 10 中的新增功能系列文章4——.NET SDK中的新增功能
  • 深入理解 setTimeout 和 setInterval
  • G. Tree Destruction
  • Windows Docker 安装
  • rust 全局变量片段
  • CVE-2021-26120 PHP Smarty模版代码注入漏洞 (复现)
  • 剑指offer-18、⼆叉树的镜像
  • 基于多代理协作的智能电子取证解决方案
  • 实用指南:老电脑PE下无法读取硬盘的原因
  • doris在各大公司生产实践方案和优化总结
  • OAuth的奇妙世界:漏洞赏金版
  • XYD 8/1 归并排序与逆序对的性质以及应用
  • 更复杂的代码,为何跑得快了10倍?一次Draw Call优化引发的思考