C题写40多分钟,D题想不出,又靠rols上分,菜哭.jpg。rols的做法十分好理解,我们按二进制位数来考虑,看a数组中有多少个包含1<<i,b数组中有多少个包含1<<i,存到ca数组和cb数组中,如果个数奇偶性不一样,就是错的,否则就先安排那些同时给a和b添加上1<<i这一位的位置,给他们加上1<<i,如果ca数组还有剩余,也就是ca[0]>cb[0],那么久给ans[ca[j]][1]安排上,cb数组还有剩余,就给ans[1][cb[j]]安排上。
奇偶性不一样的时候,说明第一行或者第一列的1无法抵消变成相同的,那么就满足不了。
此题另外一种,cf官方题解直接给第一排第一列安排,其他全是0,然后比较一下ans[1][1]计算出来的是不是一样的就行了。然而我并没有想得很清楚,不过感觉大致是对的
#include<bits/stdc++.h>
using namespace std;
const int maxn=110;
int n,m;
int a[maxn],b[maxn],ca[maxn],cb[maxn];
long long ans[maxn][maxn];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
scanf("%d",&b[i]);
for(int i=0;i<=30;i++)
{
ca[0]=cb[0]=0;
for(int j=1;j<=n;j++)
if((a[j]&(1<<i)))ca[++ca[0]]=j;
for(int j=1;j<=m;j++)
if((b[j]&(1<<i)))cb[++cb[0]]=j;
if((ca[0]&1)!=(cb[0]&1))
{
printf("NO");
return 0;
}
for(int j=1;j<=ca[0]&&j<=cb[0];j++)
ans[ca[j]][cb[j]]+=(1<<i);
if(ca[0]>cb[0])for(int j=cb[0]+1;j<=ca[0];j++)
ans[ca[j]][1]+=(1<<i);
else for(int j=ca[0]+1;j<=cb[0];j++)
ans[1][cb[j]]+=(1<<i);
}
printf("YES\n");
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
printf("%lld%c",ans[i][j],(j==m?'\n':' '));
return 0;
}