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 ...
随机推荐
- WebSeal单点登陆
WebSeal单点登陆 作为学习整理,部分内容来自网络和官方文档. LDAP LDAP可以看作一种数据库,分为客户端和服务端.服务端是用来存放资源,客户端用来操作资源.它是一种树形存储结构,遍历起来会 ...
- 【转摘】TFS上分支和标签的用法
引用路径:http://blog.csdn.net/cxzhq2002/article/details/8518250 什么时候用分支: 例如为某个客户定制的专用版本,和主干的特性有很大差别.不具通 ...
- linux下,把屏幕竖起来
xrandr -o left 向左旋转90度 xrandr -o right 向右旋转90度 xrandr -o inverted 上下翻转 xrandr -o normal 回到正常角度
- 1014-31-首页12-显示weibo未读数--后台运行---定时器
/** * 当app进入后台时调用 */- (void)applicationDidEnterBackground:(UIApplication *)application{ /** ...
- PTA 7-10(图) 旅游规划 最短路问题
7-10(图) 旅游规划 (25 分) 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果 ...
- Poweroj:2425-跳台阶(经典递推)
题目链接:https://www.oj.swust.edu.cn/problem/show/2425 跳台阶 Edit Manage Data Rejudge Time Limit: 1000 MS ...
- POJ:2456-Aggressive cows
Aggressive cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 18313 Accepted: 8716 Desc ...
- [Codeforces976E]Well played!(贪心)
[不稳定的传送门] Solution 首先可以证明,hp翻倍的操作一定是在同一个生物上最优 Code #include <cstdio> #include <algorithm> ...
- Linux命令、权限
一.新建用户natasha,uid为1000,gid为555,备注信息为“master”: groupadd -g 555 natasha useradd -u 1000 -g 555 -c mast ...
- CodeForces 873D Merge Sort 构造 分治
题意 给出一个归并排序的算法\(mergesort\),如果对于当前区间\([l, r)\)是有序的,则函数直接返回. 否则会分别调用\(mergesort(l, mid)\)和\(mergesort ...