本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题意
给你a和b序列,c序列由得到,现在问你在能对b序列以任意方式排列的情况下,c序列按位并的和是多少
思路
首先能确定的是:我们需要尽量使高位1能在按位并时保留下来,因而就形成了一个大致的解题思路:从30位到0位,判断能否保留每一位。 为了使选取的某一位保留,需要使a和b中的每一对数字,这里为了方便处理,于是将b按位取反,于是变成了,但这是脱离其它位单独看某一位的情况,因而我们可以设置一个ans,当某一位能被保留下来时,就将该位加入ans中,同时,在判断第i位能否被保留时,只需要判断ans|能否被保留。
using namespace std;
#define endl '\n'
typedef long long ll;
int read()
{
int num=0;
char c=getchar();
while(c<'0' || c>'9') c=getchar();
while(c>='0' && c <='9')
{
num=num*10+c-'0';
c=getchar();
}
return num;
}
int a[100005],b[100005];
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];
b[i] = ~b[i];
}
int ans = 0;
for(int i = 30; i >= 0; i--){
if(i == 4){
cout<<"\n";
}
int sum = 0,cnta = 0,cntb = 0;
vector<int>aa,bb;
for(int j = 1; j <= n; j++){
aa.push_back(a[j]&(ans|1<<i));
bb.push_back(b[j]&(ans|1<<i));
}
sort(aa.begin(),aa.end());
sort(bb.begin(),bb.end());
for(int j = 0; j < n; j++){
if(aa[j] != bb[j])break;
if(j == n-1)ans|=1<<i;
}
}
cout<<ans<<endl;
}
int main()
{
int t;
t=read();
while(t--)
{
solve();
}
}```