D. Vasya And The Matrix(位运算+矩阵构造)

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;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/108563269