好的20种位运算技巧:http://blog.csdn.net/zmazon/article/details/8262185
hdu6186
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN = 100005;
int a[MAXN];
int b[40];
int Pow(int n,int m)
{
int i,j;
int sum = 1;
for(i = 0;i < m;++i)
{
sum *= n;
}
return sum;
}
int main()
{
int n,q;
while(~scanf("%d %d",&n,&q))
{
int i,j;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(i = 0;i < n;++i)
{
scanf("%d",&a[i]);
}
for(i = 0;i < n;++i)
{
for(j = 0;j <= 31;++j)
{
if((a[i] >> j) & 1 == 1)
{
b[j]++;
//记录每个数在每个位上1出现的个数
}
}
}
/*for(j = 0;j <= 31;++j)
{
printf("%d ",b[j]);
}
cout<<endl;*/
int x;
for(i = 0;i < q;++i)
{
scanf("%d",&x);
int m = 0,k = 0,p = 0;
//利用与,或,异或的特性来求解
for(j = 0;j <= 31;++j)
{
int y = (a[x -1] >> j) & 1;
if(y != 1)
{
if(b[j] == n - 1)
{
m += Pow(2,j);
}
if(b[j] > 0)
{
k += Pow(2,j);
}
if((n - 1) % 2 == 0)
{
if(b[j] % 2 != 0)
{
p += Pow(2,j);
}
}
else{
if(b[j] % 2 != 0)
{
p += Pow(2,j);
}
}
}
else{
if(b[j] - 1 == n - 1)
{
m += Pow(2,j);
}
if(b[j] - 1 > 0)
{
k += Pow(2,j);
}
if(b[j] - 1 > 0){
if((n - 1) % 2 == 0)
{
if((b[j] - 1) % 2 != 0)
{
p += Pow(2,j);
}
}
else{
if((b[j] - 1) % 2 != 0)
{
p += Pow(2,j);
}
}
}
}
}
printf("%d %d %d\n",m,k,p);
}
}
return 0;
}