https://codeforces.com/problemset/problem/1016/D
一个矩阵,你知道每行,每列异或后的结果,然后还原这个矩阵,如果不能还原输出NO。
假如一个矩阵
x1 x2 x3 a1
x4 x5 x6 a2
b1 b2 b3
会发现a1=x1^x2^x3,a2=x4^x5^x6;b1=x1^x4;b2=x2^x5;b3=x3^x6;
可以得到:a1^a2=x1^x2^x3^x4^x5^x6;b1^b2^b3=x1^x2^x3^x4^x5^x6.所以要YES和NO的条件就出来了。
剩下的构造就当积累。一个出发的条件是0异或任何数都等于那个数。
然后构造
0 0 a1 (a1)
b1 b2 X (a2)
(b1) (b2)(b3)
为什么这样去构造呢?0异或任何数都等于那个数,所以靠一行和一列就可以了。最后那个数发现a1^b3==b1^b2^a2。
积累:
0异或任何数都等于那个数
矩阵构造换到一行一列
异或的构造适合设未知数去发现。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=200;
typedef long long LL;
LL a[maxn],b[maxn];
LL c[maxn][maxn];
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL n,m;cin>>n>>m;
LL res1=0;LL res2=0;
for(LL i=1;i<=n;i++) cin>>a[i],res1^=a[i];
for(LL j=1;j<=m;j++) cin>>b[j],res2^=b[j];
//check
if(res1!=res2){
cout<<"NO"<<endl;return 0;
}
cout<<"YES"<<endl;
for(LL j=1;j<=m-1;j++){
c[n][j]=b[j];
}
for(LL i=1;i<=n-1;i++){
c[i][m]=a[i];
}
LL ans=0;
for(LL j=1;j<=m-1;j++){
ans^=b[j];
}
ans^=a[n];
c[n][m]=ans;
for(LL i=1;i<=n;i++){
for(LL j=1;j<=m;j++){
cout<<c[i][j]<<" ";
}
cout<<endl;
}
return 0;
}