Little A has come to college and majored in Computer and Science.
Today he has learned bit-operations in Algorithm Lessons, and he got a problem as homework.
Here is the problem:
You are giving n non-negative integers a1,a2,⋯,an , and some queries.
A query only contains a positive integer p, which means you
are asked to answer the result of bit-operations (and, or, xor) of all the integers except ap .
Today he has learned bit-operations in Algorithm Lessons, and he got a problem as homework.
Here is the problem:
You are giving n non-negative integers a1,a2,⋯,an , and some queries.
A query only contains a positive integer p, which means you
are asked to answer the result of bit-operations (and, or, xor) of all the integers except ap .
Each test case begins with two positive integers n and p
in a line, indicate the number of positive integers and the number of queries.
2≤n,q≤105
Then n non-negative integers a1,a2,⋯,an follows in a line, 0≤ai≤109 for each i in range[1,n].
After that there are q positive integers p1,p2,⋯,pq in q lines, 1≤pi≤n for each i in range[1,q].
3 3 1 1 1 1 2 3
1 1 0 1 1 01 1 0
这道题其实只要维护一下前后缀和就好了啊。。那个不要就把他的前缀和后缀&。。比赛的时候没想到。
自己想到的是把所有数的二进制每一位的和存在数组里,然后每次要去掉哪个数,就把他的贡献减去。
这时看每位的和,如果是n-1,&的结果才能为1.(因为&要求两个数都为1结果才为1 ),或是有一个1即可。异或比较简单只要在异或一遍那个数即可。
#include <iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=1e5+5; int a[maxn]; int bit[35]; int x[35]; int main() { int n,q; while(cin>>n>>q) { int z=0; memset(bit,0,sizeof(bit)); long long xxor; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); if(i==1)xxor=a[1]; else xxor^=a[i]; z=0; int tmp=a[i]; while(tmp) { bit[z++]+=tmp%2; tmp/=2; } } while(q--) { int p; scanf("%d",&p); int tmp=a[p]; z=0; for(int i=0;i<=32;i++) x[i]=bit[i]; while(tmp) { int y=tmp%2; tmp/=2; x[z]-=y; z++; } long long cifang=1; int ans=0; long long tmp1=0,tmp2=0,tmp3=0; for(int i=0;i<=32;i++) { if(x[i]==n-1)tmp1+=cifang; if(x[i]>=1)tmp2+=cifang; cifang*=2; } cout<<(tmp1)<<" "<<tmp2<<" "<<((xxor^a[p]))<<endl; } } return 0; }