SOS例题 CF165E
题意
n 个数 , 若 a[i] & a[j] == 0 ,则称 a[i] 与 a[j] 相融。
对于每个 a[i] 输出 n个数中(除自己)与他相融的一个数 , 否则输出 -1。
(n<=1e6) (a[i]<=4e6)
分析
求最大相融数,考虑子集dp(SOS)
a&b==0 ,实际上就是 b 是 (a补集) 的子集
解题
对于 a[i] , 存 s[i]= ( ( 1 << 22 ) - 1 ) ^ a[i] ,即为 a[i] 补集
考虑子集 dp
f[x] 为 x 子集贡献最大值
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1000000+100,m=22;
int n,a[N],f[(1<<22)+100];
int main(){
cin>>n;
for(int i=1;i<=n;i++) {
cin>>a[i];
f[a[i]]=a[i];
}
for(int i=0;i<m;i++){
for(int j=0;j<=(1<<22);j++){
if(j&(1<<i)) f[j]=max(f[j],f[(1<<i)^j]);
}
}
for(int i=1;i<=n;i++){
int x=((1<<22)-1)^a[i];
cout<<(f[x]?f[x]:-1)<<" ";
}
return 0;
}

浙公网安备 33010602011771号