Codeforces 165E Compatible Numbers(二进制+逆序枚举)
4 seconds
256 megabytes
standard input
standard output
Two integers x and y are compatible, if the result of their bitwise "AND" equals zero, that is, a & b = 0. For example, numbers 90(10110102) and 36 (1001002) are compatible, as 10110102 & 1001002 = 02, and numbers 3 (112) and 6 (1102) are not compatible, as 112 & 1102 = 102.
You are given an array of integers a1, a2, ..., an. Your task is to find the following for each array element: is this element compatible with some other element from the given array? If the answer to this question is positive, then you also should find any suitable element.
The first line contains an integer n (1 ≤ n ≤ 106) — the number of elements in the given array. The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 4·106) — the elements of the given array. The numbers in the array can coincide.
Print n integers ansi. If ai isn't compatible with any other element of the given array a1, a2, ..., an, then ansi should be equal to -1. Otherwise ansi is any such number, that ai & ansi = 0, and also ansi occurs in the array a1, a2, ..., an.
2
90 36
36 90
4
3 6 3 6
-1 -1 -1 -1
5
10 6 9 8 2
-1 8 2 2 8
题目链接:Codeforces 165E
看到题目可以发现这题显然是要打表的,而且可以发现除了对应的1位必定要为0,其他位却是任意的,对每一个符合的数都去枚举任意一位可任意取值的位到底是0还是1,复杂度会变成指数级别,那么可以间接地进行递推,比如00 0110的一开始对应数字为11 1001,其他与00 0110对应数字符合xx x00x的形式,其中x表示可以任意取0或1,反正只要后面那两个1的位置为0即可,那么我们可以一位一位地慢慢枚举让哪一位变成,从xxxx x00x递推到0xxx x00x、x0xx xx0x、xx0x x00x、xxx0 x00x、xxxx 0x00x、……,一开始可能会想着这样会不会漏了其它不止变动一位的情况吧,但是实际上是不会的,这样往后推1位之后,后面的位只要让循环从大到小遍历,就会依次被枚举,即从0xxx x00x可以推到00xx x00x以至确定3位、4位的情况,当然我们是枚举把哪一位变成0,遇到已经是0的位就不用处理了,最后说一下为什么要从大到小,因为是枚举某一位$i$将其从1变成0,数字必定会减小$2^i$,因此是从大的数推到小的数,这样复杂度就只有几千万的循环了。
代码:
#include <stdio.h>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <string>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 1e6 + 7;
const int M = 22;
int arr[N];
int rev[1 << M]; int main(void)
{
int n, i, j;
while (~scanf("%d", &n))
{
int one = (1 << 22) - 1;
CLR(rev, 0);
for (i = 0; i < n; ++i)
{
scanf("%d", arr + i);
int op = arr[i] ^ one;
rev[op] = arr[i];
}
for (i = one; i >= 0; --i)
{
if (rev[i])
{
for (j = 0; j < M; ++j)
{
if (((i >> j) & 1) == 1)//i的对应位为1才需要变成0
{
int v = i ^ (1 << j);//将i的第j位从1变成0
rev[v] = rev[i];
}
}
}
}
for (i = 0; i < n; ++i)
printf("%d%c", rev[arr[i]] ? rev[arr[i]] : -1, " \n"[i == n - 1]);
}
return 0;
}
Codeforces 165E Compatible Numbers(二进制+逆序枚举)的更多相关文章
- CodeForces 165E Compatible Numbers(位运算 + 好题)
wo integers x and y are compatible, if the result of their bitwise "AND" equals zero, that ...
- C语言整数按照二进制逆序,输出逆序后的整数值
问题来源,今天早上和一舍友吃早餐的时候谈到的一个问题,将一个整数按照二进制逆序,然后输出逆序后的数值. 我们知道数值在内存中都是以二进制的形式存放的,假如我们是32位机,每8位为一个字节,int型在3 ...
- CFdiv2 165E. Compatible Numbers 子集枚举
传送门 题意: 给出一个序列,输出每个数x对应的一个ans,要求ans在数列中,并且ans & x = 0:数列的每个数小于(4e6) 思路: 这道题的方向比较难想.想到了就比较轻松了,可以 ...
- 2018ICPC徐州区域赛网络赛B(逆序枚举或者正序深度搜索)
#include<bits/stdc++.h>using namespace std;int n,m,k,l;int x[1007],y[1007],z[1007];int dp[1007 ...
- 二进制打印与逆序_C语言(转)
//二进制逆序 by MoreWindows( http://blog.csdn.net/MoreWindows ) #include <stdio.h> //二进制打印函数 templa ...
- hdu.1043.Eight (打表 || 双广 + 奇偶逆序)
Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- C++ 排序函数 sort(),qsort()的含义与用法 ,字符串string 的逆序排序等
上学时我们很多学了很多种排序算法,不过在c++stl中也封装了sort等函数,头文件是#include <algorithm> 函数名 功能描述 sort 对给定区间所有元素进行排序 st ...
- POJ 2541 Binary Witch(逆序KMP,好题)
逆序KMP,真的是强大! 参考链接,下面有题意解释:http://blog.sina.com.cn/s/blog_6ec5c2d00100tphp.htmlhttp://blog.csdn.net/s ...
- 笔记-NSArray 逆序reverseObjectEnumerator 及 NSEnumerator 遍历
//1.原始数组 NSMutableArray *array = [NSMutableArray arrayWithObjects:@"1",@"2",@&qu ...
随机推荐
- securecrt颜色设置
https://blog.csdn.net/zq710727244/article/details/53909801
- c++ 11 线程池的简单封装
#include <condition_variable> #include <queue> #include <thread> #include <vect ...
- DFS练习-HDU1010
题目来源:HDU1010 DFS的基本原则已经差不多了,但是一些技巧仍然比较难想,所以还是加强练习,然后总结一下. 还是先看题意 ,指定迷宫的长,宽以及走出迷宫的具体时间N,M,T. 其中(1 < ...
- python基础数据类型之列表,元组操作
一.列表的索引和切片1.列表的索引列表和字符串一样样拥有索引 lst = ["a","b","c"] print(lst[0]) # 获取第 ...
- java后台poi根据模板导出excel
public class ExcelUtils { private static final String INSPECTIONRECORD_SURFACE_TEMPLET_PATH = " ...
- C#基础-委托与事件
委托 delegate是申明委托的关键字 返回类型都是相同的,并且参数类型个数都相同 委托声明 delegate double DelOperater(double num1, double num2 ...
- <Docker学习>4. docker容器的使用
简单的说, 容器是独立运行的一个或一组应用, 以及它们的运行态环境. 对应的, 虚拟机可以理解为模拟运行的一整套操作系统( 提供了运行态环境和其他系统环境) 和跑在上面的应用.容器的运行是基于镜像的. ...
- 虚拟机linux桥接联网问题
Linux系统为redhat5.8 虚拟机的版本:vm8.0 本人刚刚开始接触linux,今日需要通过linux进行联网,因此也学习了一点点关于虚拟机的联网的知识,在此与大家进行分享,希望大家可以之处 ...
- C语言进阶——浮点数的秘密03
浮点数在内存中的储存方式为:符号位 指数位 尾数 float和double类型的数据在计算机内部的表实方法是一样的,但是由于所占的存贮空间的不同,其分别能表示的数值范围和精度不同. 类型 f符号位 指 ...
- perl连接mysql数据库
首先需要安装 ppm install DBD::mysql use strict; use DBI; my $host = "localhost"; # 主机地址 my $driv ...