D
题意
给定长度为n的数组a和数组b,b数组的顺序可以随意修改,定义数组c[i] = a[i] ^ b[i],输出最大化的c[1] & c[2] & … c[n]的值。
思路
考虑二进制从高往低枚举,如果当前位置能实现全部a和b异或出1,则记录答案,并且下一次枚举是要加上这个答案
代码实现
void solve()
{
int n;
cin >> n;
for(int i = 1 ; i <= n ; i ++) cin >> a[i];
for(int i = 1 ; i <= n ; i ++) cin >> b[i];
int ans = 0;
for(int j = 30 ; j >= 0 ; j --)
{
ans |= (1 << j);
map<int,int> ma , mb;
// 表示对于当前答案a[i], b[i] 的 1的分布的个数
for(int i = 1 ; i <= n ; i ++)
ma[a[i] & ans] ++, mb[b[i] & ans] ++;
bool ok = true;
// 如果当前对于每一个a[i] & ans 对应的数,b[i] 都有刚刚好异或成ans的个数
//那么这个答案是可以构造出来的
for(int i = 1 ; i <= n ; i ++)
if(ma[ans & a[i]] != mb[ans ^ (ans & a[i])])
ok = false;
if(!ok) ans -= (1 << j);
}
cout << ans << '\n';
}