题目链接

https://ac.nowcoder.com/acm/contest/8564/B

解题思路

假设x=0,y=1,那么x&0=0,y&0=0;x|1=1,y|1=1;x^1=1,y^1=0。
对于每一位而言,如果经过若干次操作,x从0变成0并且y从1变成0,说明这若干次的操作对本位二进制产生的影响与本位二进制与0相与的效果相同;
类似的,x从0变成1并且y从1变成1,说明这若干次的操作对本位二进制产生的影响与本位二进制与1相或的效果相同;
类似的,x从0变成1并且y从1变成0,说明这若干次的操作对本位二进制产生的影响与本位二进制与1相异或的效果相同。
详见代码。

AC代码

#include<bits/stdc++.h>
#define ll long long

using namespace std;
const int N=5e5+100;
int n,op[N],a[N];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>op[i]>>a[i];
    int And=(1<<20)-1,Or=0,Xor=0;//初始化
    for(int i=0;i<20;i++)//遍历二进制每一位
    {
        int x=0,y=1;
        for(int j=1;j<=n;j++)//遍历每个操作
        {
            int tmp=(a[j]>>i)&1;//得到每个操作对第i位的操作数
            if(op[j]==1)
            {
                x&=tmp;
                y&=tmp;
            }
            else if(op[j]==2)
            {
                x|=tmp;
                y|=tmp;
            }
            else 
            {
                x^=tmp;
                y^=tmp;
            }
        }
        if(!x&&!y) And-=(1<<i);//x、y都变成0,说明当前位与0相与
        else if(x&&y) Or+=(1<<i);//x、y都变成1,说明当前位与1相或
        else if(x&&!y) Xor+=(1<<i);//x、y都变成与原来相反的数,说明当前位与1相异或
    }
    cout<<3<<endl<<1<<' '<<And<<endl<<2<<' '<<Or<<endl<<3<<' '<<Xor<<endl;
}