CF2249D Xor Permutation Matrix
在 Print 之前
小店解析:切了 D2F/D1D 没切 D2E/D1C。
题解
考虑什么情况无解。
对于 \(n = 2\),\(x \ne 0\) 时无解。
手玩一下 \(n = 3\) 发现对于 \(x = 0,1,2\) 都无解(于是赛时直接判掉 \(n \ne 2^p\) 的情况),思考后发现:对于 \(n > 2\),如果 \(n\) 并不是 2 的整数次幂,那也无解。
对于 \(x = 0\) 的构造似乎也是显然的。
考虑如何构造其他情况。
我们可以把目标矩阵 \(A\) 拆解为三个独立的部分:
\(A_{i,j} = C_i \oplus C_j \oplus M_{i,j}\)。
其中,\(M_{i,j}\) 在 \(i\) 和 \(j\) 都是偶数时为 \(x\),其他情况为 \(0\)。
这个方法的好处就在于对于 \(C_i\) 和 \(C_j\),在统计这个矩阵时不会做出任何贡献。
考虑如何构造 \(C\)。
为了让包含了 \(M_{i,j}\) 的每一行/列仍然是排列,我们需要把 \(0\) 到 \(n-1\) 分成若干个互不相交的数对 \((y, y \oplus x)\),我们将这些数对分成两部分处理。
把其中一个集合的数放在 \(C\) 的偶数下标位置,把 另一个集合中的数放在 \(C\) 的奇数下标位置即可。这样一来,无论是在异或 0 还是异或 \(x\) 的情况下,行和列都是一个从 \(0\) 到 \(n-1\) 的排列。
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstring>
#ifdef _WIN32
#define getchar _getchar_nolock
#define putchar _putchar_nolock
#else
#define getchar getchar_unlocked
#define putchar putchar_unlocked
#endif
#define pll pair<ll,ll>
#define pld pair<ld,ld>
typedef long long ll;
typedef long double ld;
typedef __int128 i128;
namespace io {
using namespace std;
template<typename T> void debug (T x) {
cerr<<x<<'\n';
}
template<typename T> void debuglen (T x) {
cerr<<x<<' ';
}
template<typename T,typename...Args> void debug (T x,Args...args) {
cerr<<x<<' ';
debug(args...);
}
template<typename T> void debug (T *lt,T *rt) {
ll len=rt-lt;
for (ll i=0;i<len;i++) {
debuglen(*(lt+i));
}
cerr<<'\n';
}
inline ll read () {
char x=getchar();
ll ans=0,f=1;
while (x<'0'||x>'9') {
if (x=='-') {
f=-1;
}
x=getchar();
}
while (x>='0'&&x<='9') {
ans=(ans<<1)+(ans<<3);
ans+=(x^'0');
x=getchar();
}
return ans*f;
}
template <typename T> void write (T x) {
if (x<0) {
putchar('-');
x=-x;
}
if (x>=10) {
write(x/10);
}
putchar(x%10+'0');
}
template <typename T> inline void print (T x) {
write(x);
putchar('\n');
}
template <typename T> inline void printlen (T x) {
write(x);
putchar(' ');
}
template <typename T,typename...Args> inline void print (T x,Args...args) {
printlen(x);
print(args...);
}
template <typename T> inline void print (T *lt,T *rt) {
ll len=rt-lt;
for (ll i=0;i<len;i++) {
if (i==len-1) {
print(*(lt+i));
return ;
}
printlen(*(lt+i));
}
}
}
using namespace io;
const ll N=25e2+5,mod=1e9+7,inf=2e18;
const ld eps=1e-6;
ll n,x,num[N];
vector<pll> vl;
bool vis[N];
inline void solve () {
n=read(),x=read();
if ((n&(n-1))!=0) {
puts("-1");
return ;
}
if (x==0) {
for (ll i=1;i<=n;i++) {
for (ll j=1;j<=n;j++) {
print((i-1)^(j-1));
putchar(' ');
}
puts("");
}
return ;
}
if (n==2) {
puts("-1");
return ;
}
vl.clear();
for (ll i=0;i<n;i++) {
vis[i]=0;
}
for (ll i=0;i<n;i++) {
if (vis[i]) {
continue;
}
ll xl=i^x;
vis[i]=vis[xl]=1;
vl.push_back({i,xl});
}
ll len=n/4;
for (ll i=0;i<len;i++) {
num[2*i+1]=vl[i].first;
num[2*i+2]=vl[len+i].first;
num[2*(i+len)+1]=vl[i].second;
num[2*(i+len)+2]=vl[len+i].second;
}
for (ll i=1;i<=n;i++) {
for (ll j=1;j<=n;j++) {
ll val=num[i]^num[j];
if (!(i&1)&&!(j&1)) {
val^=x;
}
print(val);
putchar(' ');
}
puts("");
}
}
int main () {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ll T=read();
while (T--) {
solve();
}
return 0;
}

浙公网安备 33010602011771号