题目:点击打开链接
题意:给你n个数,q次查询,每次查询的输出为去掉第q个数之后的n-1个数的与运算、或运算、异或运算结果。
思路:
首先异或运算的特征,边读入边异或,最后查询哪个在与之异或即可;
对于与运算,想到多个二进制数相与,只要某个数的某一位上是0,与运算的结果该位上的数为0,所有数的该位上的数都为1时结果才为1;
对于或运算,只要某个数的某一位上的数为1,结果为1,所有数该位为0,结果为0。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int a[maxn];
int num1[33],num0[33],p1[33],p0[33];
int main()
{
int n,q;
while(~scanf("%d%d",&n,&q))
{
memset(num0,0,sizeof(num0));
memset(num1,0,sizeof(num1));
int _xor=0,_and=0,_or=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
_xor^=a[i];
for(int j=31; j>=0; j--)
{
if(1&(a[i]>>j))
num1[j]++;
else
num0[j]++;
}
}
for(int i=1; i<=q; i++)
{
int p;
scanf("%d",&p);
memset(p0,0,sizeof(p0));
memset(p1,0,sizeof(p1));
for(int j=31; j>=0; j--)
{
if(1&(a[p]>>j))
p1[j]++;
else
p0[j]++;
}
for(int j=31; j>=0; j--)
if((num1[j]==n-1&&p1[j]==0)||(num1[j]==n&&p1[j]==1))
_and=_and*2+1;
else
_and=_and*2+0;
for(int j=31; j>=0; j--)
if(num1[j]-p1[j]!=0)
_or=_or*2+1;
else
_or=_or*2+0;
_xor=_xor^a[p];
printf("%d %d %d\n",_and,_or,_xor);
_xor=_xor^a[p];
}
}
return 0;
}