显然,可以用三个操作得到所有答案。
利用x=0和y=1来存储每一位在进行n次操作后的变化。
操作完后若:
x=0且y=0,说明不论什么数,操作完之后这一位必定为0,那么可以得出要在该位 &0
x=1且y=0,说明操作完就是取反,那么在该位需要 ^1 (0 ^ 1 = 1,1 ^ 0 = 0)
x=0且y=1, 保持不变即可, 那么 | 0 、& 1 、 ^ 0(1 ^ 0 = 1,0 ^ 0 = 0) 都是可以的。
x=1且y=1, 可以想到 | 1
有结论后,就是用一个全为1的And,和全为0的Or,和Xor来存每一种操作应该在哪一位对数字进行变化
代码如下:
int a[N],op[N]; int main(){ int n; scanf("%d",&n); int And=(1<<20)-1,Or=0,Xor=0; for(int i=1;i<=n;i++) scanf("%d%d",&op[i],&a[i]); for(int j=0;j<20;j++){ int x=0,y=1; for(int i=1;i<=n;i++){ int tmp = (a[i]>>j) & 1;//取第j位 if(op[i]==1){ x&=tmp; y&=tmp; } if(op[i]==2){ x|=tmp; y|=tmp; } if(op[i]==3){ x^=tmp; y^=tmp; } } if(!x&&!y) And^=(1<<j); else if(!x&&y); else if(x&&!y) Xor^=(1<<j); else&nbs***bsp;^= (1<<j); } printf("3\n"); printf("1 %d\n",And); printf("2 %d\n",Or); printf("3 %d\n",Xor); return 0; }