位运算知识
位与: 可以看作乘法& 只有当两位都为1结果才为1,否则为0
位或: 可以看作不进位加法| 只有当两位都为0的时候结尾才为0,否则为1
异或 : ^ 当两位不同的时候结尾才为1,否则为0;
按位取反:0变1,1变0;
1.P1469 找筷子 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
异或的两个小小的性质:
- k 个相同的数的异或和,当 k 为奇数时,结果是这个数本身,否则结果是 00。
- 任何数与 00 的异或值是它本身。

1 #include<cstdio> 2 int x,n,ans; 3 int main(){ 4 scanf("%d",&n); 5 for(int i=1;i<=n;i++)scanf("%d",&x),ans^=x; 6 printf("%d\n",ans); 7 }
2.Problem - 1903B - Codeforces
按位或其实是一个挺强的限制条件,他相当于得到了如果Mi,j 中某个二进制位是 0,则 ai,aj 中该位都得是 0。
至于 Mi,j 中是 1 的二进制位,我们令 ai,aj 该位都是 1,这样在处理其他的 Mi,j 的时候,利用上面的限制条件去看他能否保住。
整个矩阵做完之后,得到了所有限制条件都满足的 ai,然后依次判断 aiORaj 是否等于Mi,j 即可。

1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 5 const int inf = 0x3f3f3f3f; 6 const int N = 2e3 + 5; 7 8 9 int main(){ 10 ios_base::sync_with_stdio(0); 11 cin.tie(0); 12 int t; 13 cin>>t; 14 while(t--){ 15 int n; 16 cin>>n; 17 int a[N][N]; 18 int arr[N]; 19 if(n==1){ 20 cin >> a[0][0]; 21 cout<<"YES"<<endl<<0<<endl; 22 continue; 23 } 24 25 for(int i = 0;i < n;i++){ 26 arr[i] = (1<<30) - 1; 27 } 28 29 for(int i = 0;i < n;i++){ 30 for(int j = 0;j < n;j++){ 31 cin>>a[i][j]; 32 if(i != j){ 33 arr[i] &= a[i][j]; 34 arr[j] &= a[i][j]; 35 } 36 } 37 } 38 bool ok = true; 39 for(int i = 0;i < n;i ++){ 40 for(int j = 0;j < n;j ++){ 41 if(i != j && (arr[i] | arr[j]) != a[i][j]){ 42 ok = false; 43 } 44 } 45 } 46 if(!ok){ 47 puts("NO"); 48 } 49 else{ 50 cout<<"YES\n"; 51 for(int i = 0;i < n;i++){ 52 cout<<arr[i]<<" "; 53 } 54 cout<<endl; 55 } 56 } 57 }