Codeforces 165E Compatible Numbers 题解

题目传送门:CodeforcesLuogu

思路

高维前缀和

高维前缀和

把数的二进制看成一个集合,二进制的每一位为 \(1\) 为全集 \(V\)

根据题目描述,若两数 \(a, b\) 相容,则 \(a \operatorname{and} b = 0\),容易发现,\(b \in \complement_{V}a\),所以我们只需要用高维前缀和处理出 \(\complement_{V}a\) 的一个元素即可。若没有元素,输出 -1 就行了。

点击查看代码
#include <iostream>
#include <cstdio>

using namespace std;

void RD() {}
template<typename T, typename... U> void RD(T &x, U&... arg) {
    x = 0; int f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    x *= f; RD(arg...);
}

const int N = 1e6 + 5, B = (1 << 22) + 5;

#define LF(i, __l, __r) for (int i = __l; i <= __r; i++)
#define RF(i, __r, __l) for (int i = __r; i >= __l; i--)

int n, a[N];
int f[B];

int main() {
    RD(n);
    LF(i, 1, n) RD(a[i]), f[a[i]] = a[i];
    LF(i, 0, (1 << 22) - 1) LF(j, 0, 21) 
        if ((i & (1 << j)) && f[i ^ (1 << j)]) f[i] = f[i ^ (1 << j)];
    LF(i, 1, n) printf("%d ", f[((1 << 22) - 1) ^ a[i]] ? f[(1 << 22) - 1 ^ a[i]] : -1);
    return 0;
}
posted @ 2024-08-09 13:11  FRZ_29  阅读(3)  评论(0编辑  收藏  举报