题目链接:点击这里
题目大意:
给定一个长度为
n
n
n 的 序列
a
i
a_i
ai ,和一个长度为
m
m
m 的序列
b
i
b_i
bi ,求构造一个
n
×
m
n\times m
n×m 的矩阵,其满足第
i
i
i 行的异或和为
a
i
a_i
ai ,第
i
i
i 列的异或和为
b
i
b_i
bi
题目分析:
首先判断是否有解,由于
a
i
a_i
ai 的异或和 和
b
i
b_i
bi 的异或和都是整个矩阵所有元素的异或和,所以如果
a
i
a_i
ai 的异或和不等于
b
i
b_i
bi 那么就无解的
接下来考虑如何构造答案,设答案矩阵为
m
p
[
i
]
[
j
]
mp[i][j]
mp[i][j]
把
m
p
[
1
]
[
1
]
mp[1][1]
mp[1][1] 填成
a
1
a_1
a1 ^
b
2
b_2
b2 ^
b
3
b_3
b3…
b
m
b_m
bm ,然后
m
p
[
1
]
[
i
]
mp[1][i]
mp[1][i] 设成
b
i
b_i
bi ,这样第一行的异或和就是
a
1
a_1
a1
m
p
[
i
]
[
1
]
(
i
>
1
)
mp[i][1](i>1)
mp[i][1](i>1) 设成
a
i
a_i
ai ,这样第一列的元素和就是
a
1
a_1
a1 ^
b
2
b_2
b2 ^
b
3
b_3
b3…
b
m
b_m
bm ^
a
2
a_2
a2 ^ …^
a
n
a_n
an =
b
2
b_2
b2 ^
b
3
b_3
b3…
b
m
b_m
bm ^
a
1
a_1
a1 ^ …
a
n
a_n
an = b_2$ ^
b
3
b_3
b3…
b
m
b_m
bm ^
b
1
b_1
b1 ^ …
b
n
b_n
bn =
b
1
b_1
b1 ,这样就保证了第一列的异或和为
b
1
b_1
b1
其余元素全填
0
0
0 即可,这样的矩阵就是合法构造方案
具体细节见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int read()
{
int res = 0,flag = 1;
char ch = getchar();
while(ch<'0' || ch>'9')
{
if(ch == '-') flag = -1;
ch = getchar();
}
while(ch>='0' && ch<='9')
{
res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';
ch = getchar();
}
return res*flag;
}
const int maxn = 2e3+5;
const int mod = 1e9+7;
const double pi = acos(-1);
const double eps = 1e-8;
int n,m,x,y,a[maxn],b[maxn],mp[maxn][maxn];
int main()
{
n = read(),m = read();
for(int i = 1;i <= n;i++) a[i] = read(),x ^= a[i];
for(int i = 1;i <= m;i++) b[i] = read(),y ^= b[i];
if(x != y) return 0*puts("NO");
else puts("YES");
for(int i = 2;i <= m;i++) mp[1][i] = b[i];
y ^= b[1];
for(int i = 1;i <= n;i++) mp[i][1] = i==1 ? a[i]^y : a[i];
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++) printf("%d%c",mp[i][j],j==m ? '\n' : ' ');
return 0;
}