题解:P14148 错觉
很明显的随机化,直接开始分析。
我们设一开始的 \(p\) 为标准排列,计算此时的 \(\bigoplus\limits_{i=1}^n (p_i+k\times i)\),然后进行多次随即操作,每次随机挑选两个位置 \(a,b\),交换 \(p_a,p_b\),计算此时的值(注意这里的计算必须是 \(\Theta \left ( 1 \right )\) 的,不然会 TLE)。如果这个值为 \(0\),直接输出,否则再次执行上面的操作,随机挑选两个位置。
为了判断无解的情况,我们只执行上面判断操作 \(28000000\) 遍。若还是没找到符合的状况,直接判无解输出 \(-1\)。
结合代码好理解,代码如下:
#include <bits/stdc++.h>
#define int long long
using namespace std;
mt19937 rnd(chrono::system_clock().now().time_since_epoch().count());
const int N = 1e6 + 5;
int n,k;
int p[N];
signed main()
{
cin>>n>>k;
int ans = 0;
for(int i=1; i<=n; i++)
{
p[i]=i;
}
for(int i=1; i<=n; i++)
{
ans ^= (p[i]+i * k);
}
for(int i = 1; i <= 28000000; i++) {
int a = rnd()%n+1;
int b = rnd()%n+1;
ans ^= (p[a]+a * k);
ans ^= (p[b]+b * k);
swap(p[a],p[b]);
ans ^= (p[a]+a * k);
ans ^= (p[b]+b * k);
if(ans==0) {
for (int j = 1; j <= n; j++) {
cout << p[j] << " ";
}
return 0;
}
}
cout << -1;
return 0;
}

浙公网安备 33010602011771号